Using TVPosterImage in TVUIKit for tvOS 12 - swift

tvOS 12 has a new framework TVUIKit, which introduces the lockup views. The class I am interested in is TVPosterView, which is basically designed as such:
Swift 4.2
open class TVPosterView : TVLockupView { // One may use UIControl to implement it in iOS
public init(image: UIImage?)
open var image: UIImage? // default is nil
open var title: String?
open var subtitle: String?
}
In my storyboard I have added an UIView element, and rightly (at least I hope so. Yesterday the IB agent kept crashing!) changed its class to TVPosterView in Identity Inspector. then in my UIViewController I have defined:
#IBOutlet var aPosterView: TVPosterView!
override func viewDidLoad() {
super.viewDidLoad()
if let myIcon = UIImage(named: "icon.png") {
self.aPosterView = TVPosterView(image: myIcon)
self.aPosterView.title = "My Title"
self.aPosterView.subtitle = "A Sub Title"
}
else {
print("ERROR: I couldn't load the icon!")
}
}
}
It compiles without any warning. When I run it, it just shows the UIView white background, nothing changes. I did some tests trying to add an UIImageView, but they were all inconclusive (apart, off course, when I did set the image of UIImageView to self.aPosterView.image).
I am far from being an expert, I just started learning a couple of weeks ago. Any idea about what I am missing? I thought the concept was that once I initiated the class the framework was taking care of displaying the poster with the (optional) title and subtitles, also taking care of all nice animations!

Eventually I managed to make it working programmatically. I tested both TVPosterView and TVMonogramView (basically a round button). The following code works with Xcode 10 beta 5, on tvOS 12 beta 5:
Swift 4.2
import UIKit
import TVUIKit
class SecondViewController: UIViewController {
var myPoster = TVPosterView()
var myMonogram = TVMonogramView()
override func viewDidLoad() {
super.viewDidLoad()
myPoster.frame = CGRect(x: 100, y: 100, width: 550, height: 625)
myPoster.image = UIImage(named: "image1.png")
myPoster.imageView.masksFocusEffectToContents = true
myPoster.title = "Poster"
myPoster.subtitle = "This is the poster subtitle"
self.view.addSubview(myPoster)
var myName = PersonNameComponents()
myName.givenName = "Michele"
myName.familyName = "Dall'Agata"
myMonogram.frame = CGRect(x: 700, y: 100, width: 500, height: 475)
myMonogram.image = UIImage(named: "image2.png")
myMonogram.title = "Monogram"
myMonogram.subtitle = "This is the Monogram subtitle"
myMonogram.personNameComponents = myName
self.view.addSubview(myMonogram)
print(myMonogram.personNameComponents)
}
}
I didn't manage to scale the poster's image with scaleAspectFit, though. Also my first image was rounded with a transparency, and only choosing a frame size that perfectly fit the squared image plus the titles (so no aspect fit needed), the glowing effect became transparent on the corners. Otherwise the whole image was opaque, using its own (quite small) rounded corners.

Related

I want to give the thumb image to NSSlider in swift

I`m working on an editor app, where I need to add image in the slider thumb as I'm doing macOS development so unfortunately I'm not able to do that in macOS, there is available in UISlider.
this is what I have and I want to insert the thumb Image as give below
I find out the solution, I hope this will help you all.
I made a NSSliderCell class and override the function drawKnob.
class CustomSliderCell: NSSliderCell {
#IBInspectable var knobImage: NSImage?{
didSet{
if let knobImage = knobImage{
self.knobImage = knobImage
}
}}
override func drawKnob(_ knobRect: NSRect) {
var rect = knobRect
rect.size = NSSize(width: rect.width, height: rect.height - 4)
self.knobImage?.draw(in: rect)
}
}
just assign this class to you nsslider cell from your storyboard and change the image on your storyboard.
enter image description here
The Result is given Below :
[This is the resultant Image][2]
enter image description here

Using a vector image with TVMonogramView

I've looked around and unfortunately there's very little on the web about the latest addition to the tvOS 12.0 which is the TVUIKit and its new controls. I have a UICollectionView with UICollectionViewCells of the following type:
import UIKit
import TVUIKit
class AirportsCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var imageView: UIImageView!
var airportView: TVMonogramView!
override func awakeFromNib() {
airportView = TVMonogramView(frame: self.contentView.frame)
airportView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(airportView)
}
}
I have some images in my assets catalog that are all PDF files and I've naturally checked the "Preserve vector data" and they work absolutely fine when I assign them to my UIImageView of choice with any given size. However, when I assign them to the image property of my TVMonogramView, I get a terrible quality on the images. They seem to have been rendered with a very low resolution.
Here's how I use them:
if let flag = UIImage(named: countryCode) {
cell.airportView.image = flag
} else {
cell.airportView.image = nil
}
How can I fix this behaviour and what is the alternative?

SystemStatusBar statusItem title being cut short on OS X

I am trying to display an OS X application statusItem in the System Status Bar and am having success with everything except the fact that the title is being cut off. I am initializing everything like so:
let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(-1)
func applicationDidFinishLaunching(aNotification: NSNotification) {
let icon = NSImage(named: "statusIcon")
icon?.template = true
statusItem.image = icon
statusItem.menu = statusMenu
statusItem.title = "This is a test title"
}
The problem is the statusItem.title is appearing like so:
As you can see the application next to mine (iStatMenuBar) is cutting off the title to my application (or something similar is happening)
If I comment out the icon for the statusItem, it works and shows the entire title but when I re-add the icon it cuts off again. Is there a way for the two (icon and title) to co exist? I have reviewed some Apple docs and may have missed a critical piece which explains this.
Thanks guys.
One option would be to assign a custom view to your statusBarItem and within that view's class override drawRect(dirtyRect: NSRect) e.g.
private var icon:StatusMenuView?
let bar = NSStatusBar.systemStatusBar()
item = bar.statusItemWithLength(-1)
self.icon = StatusMenuView()
item!.view = icon
and StatusMenuView might look like:
// This is an edited copy & paste from one of my personal projects so it might be missing some code
class StatusMenuView:NSView {
private(set) var image: NSImage
private let titleString:NSString = "really long title..."
init() {
icon = NSImage(named: "someImage")!
let myWideStatusBarItemFrame = CGRectMake(0, 0, 180.0, NSStatusBar.systemStatusBar().thickness)
super.init(frame.rect)
}
override func drawRect(dirtyRect: NSRect)
{
self.item.drawStatusBarBackgroundInRect(dirtyRect, withHighlight: self.isSelected)
let size = self.image.size
let rect = CGRectMake(2, 2, size.width, size.height)
self.image.drawInRect(rect)
let titleRect = CGRectMake( 2 + size.width, dirtyRect.origin.y, 180.0 - size.width, size.height)
self.titleString.drawInRect(titleRect, withAttributes: nil)
}
}
Now, the above might change your event handling, you'll need to handle mouseDown in the StatusMenuView class.

Show a GIF image using NSImageView

I want to show an animated gif image in my cocoa application.
I dragged the gif into Assets.xcassets in XCode. I was hoping that NSImageView can show a gif out of the box, so I tried the following code.
let imageView = NSImageView(frame: NSRect(x: 0, y: 0, width: 512, height: 512))
imageView.canDrawSubviewsIntoLayer = true
imageView.imageScaling = .ScaleNone
imageView.animates = true
imageView.image = NSImage(named: "loading-animation")
window.contentView?.addSubview(imageView)
The image does not show up. The above code works with a png image. How do I get this to work?
For me it works only if there is nothing set in the Attribute Inspector and with the code like that (hope, it will be useful for someone):
class FirstViewController: NSViewController {
#IBOutlet weak var imgImage1: NSImageView!
override func viewDidLoad() {
super.viewDidLoad()
let imgImage1 = NSImageView(frame: NSRect(x: 407, y: 474, width: 92, height: 74))
imgImage1.canDrawSubviewsIntoLayer = true
imgImage1.imageScaling = .scaleProportionallyDown
imgImage1.animates = true
imgImage1.image = NSImage(named: "mygif")
self.view.addSubview(imgImage1)
}
Enjoy :)
Xcode 12
Just add your gif file in your project (Not in Assets)
Add an NSImageView in your view controller.
Set the image name in the storyboard as your gif file name.
Tap on Animates property.
Answering my own question.
I was able to make a gif display in my app when I get the gif from a URL e.g.
imageView.image = NSImage(byReferencingURL: yourgifurl)
So, I figured there was something wrong with the way I copied the image into my project. Instead of putting the image in Assets.xcassets, I put it with the rest of source code and the gif shows up :) (but the animation speed seems to be very slow)
Suppose you have an animated gif resource named universe in an Assets.xcassets and NSImageView connected by IBOutlet named target:
...
#IBOutlet weak var target: NSImageView!
...
func applicationDidFinishLaunching(_ aNotification: Notification) {
...
target.animates = true
target.image = NSImage(data: NSDataAsset(name: "universe")!.data)
...
}
NOTE:
target.image = NSImage(named: "universe") // WILL NOT WORK!

Layering transparent images and text on top of a mapView (Swift)

I want to put a transparent box on top of a mapView and then some text on top of that.
I can do this treating the image as a button and altering the alpha setting but only the last UILabel I put in place remains black, the rest are muted.
Is this possible with Tags or something or does it have to be done programatically?
Anyway after a couple of hours sleuthing this is a working solution.
Declare your layer
#IBOutlet weak var layerView: UIView!
var myLayer: CALayer {
return layerView.layer
}
Put a UIView on your ViewController and link it to layerView.
Create a method/func to display the frame, e.g.
func displayMyFrame() {
myLayer.frame = CGRectMake(100, 100, 200, 40)
myLayer.backgroundColor = UIColor.whiteColor().CGColor
myLayer.borderWidth = 1.0
myLayer.borderColor = UIColor.redColor().CGColor
myLayer.shadowOpacity = 0.6
myLayer.cornerRadius = 5.0
myLayer.shadowRadius = 10.0
myLayer.opacity = 0.6
}
Put your UILabels on the view and change their tags to 1 (in this example).
Call the func in viewDidLoad.
displayMyFrame()
view.layer.insertSublayer(myLayer, atIndex: 1)
The atIndex: 1 means that this frame will be put behind the UILabels with a Tag of 1.
This works, hope that it helps.