Making NSView appearance vibrantDark - swift

I'm currently learning Swift, and I followed this tutorial to create an NSWindow that inherits the vibrantDark property from the AppKit in Swift. The code I added to the WindowController.swift file is as follows:
window?.titleVisibility = .hidden
window?.appearance = NSAppearance(named: NSAppearance.Name.vibrantDark)
What I'd like to do is achieve the same result for an NSPopover in my program; however, when I add the following to my LogViewController.swift file, I get an error -- the first of which is "Value of type 'NSView' has no member 'titleVisibility,'" and the second of which is "Cannot use optional chaining on non-optional value of type 'NSView.'"
view?.titleVisibility = .hidden
view?.appearance = NSAppearance(named: NSAppearance.Name.vibrantDark)
Several posts have addressed this issue for NSWindow, but I cannot find an answer that addresses NSPopover. I currently have the following condition set to open NSPopover upon clicking NSImage in the status bar:
popover.contentViewController = LogViewController.freshController()
I'm thinking that having NSPopover as NSView is what's causing the issue, but -- being as I'm still new to Swift -- I'm not sure how to diagnose this the problem. That said, I would much appreciate it if anyone could point me towards the right direction.

You should be using an NSPopover, not an NSView:
var myPopover: NSPopover?
myPopover = NSPopover.init()
myPopover?.appearance = NSAppearance(named: .vibrantDark)
If you want to use a contentViewController:
var popoverViewController: NSViewController?
myPopover?.contentViewController = self.popoverViewController

Related

Text label not updating on screen, even though it shows up on `print()`

I'm writing an application which has an NSSplitViewController as the main View-Controller. I have it linked-up so that clicking a button in the menubar will trigger an #IBAction which then calls a function in one of the sub-View-Controllers.
if let board = storyboard {
let imageController = board.instantiateController(withIdentifier: "VC_image_ID") as! VC_image
imageController.viewDidAppear() // necessary or else I'll get an "Unexpectedly found nil" later on
DispatchQueue.global().async{imageController.processImage(path)} // path variable was set earlier in the code, but not shown here
}
Inside the sub-View-Controller (named VC_image), I'm trying to change the stringValue of a label by using the following code:
public func processImage(_ path: String) {
DispatchQueue.main.async {
self.imageText.stringValue = path
print(self.imageText.stringValue)
}
}
Although the imageText.stringValue actually seems to have changed based on the fact that it prints the updated text (through the console), the text in the window never changes. Why is this happening? The reason is probably really obvious to professionals, but I'm still an amateur and can't figure it out. Thanks.

Need explanation on declaring a property lazy on a custom type

Hello so I have a UIButton and I subclassed it to a CustomButton
Now in another file I tried
private lazy var button = CustomButton()
and I got an error saying Cannot convert value of type UIButton to specified type RoundedButton
But if I do this private lazy var button: CustomButton = CustomButton()
it works. I just need an understanding why the one above doesn't work, but the one on the bottom works?
I've read that for lazy propers you can't infer types, but private lazy var button = UIButton() works.
I believe the issue is not with the "private lazy".
You have to use "button:CustomButton" because "Swift is statically typed on the other hand. Meaning variables have type. You can't place any object you want into a variable. The compiler will make sure you only place compatible objects into variables."

Erratic error in SnapKit

The following is my viewDidAppear() method with which I'm trying to prototype a feature for my app. The graphicsView instance variable is bound via the storyboard to an instance of a subclass of NSView I've written that in turn is enclosed in an NSScrollView within an NSSplitView. This code is within the view controller for that view.
override func viewWillAppear() {
super.viewWillAppear()
let red = CGColor.init(red: 1, green: 0, blue: 0, alpha: 1)
self.view.layer?.backgroundColor = red
let box = NSTextView()
self.graphicsView.addSubview(box)
box.snp.makeConstraints { (make) -> Void in
make.edges.equalTo(self.graphicsView).inset(NSEdgeInsetsMake(100, 100, self.graphicsView.bounds.height - 200, self.graphicsView.bounds.width - 300))
}
box.textStorage?.append(NSAttributedString(string: "Hello Sailor"))
box.alignCenter(self)
}
When executed, I get the error Cannot form weak reference to instance (0x6000001224e0) of class NSTextView. It is possible that this object was over-released, or is in the process of deallocation. along with the usual EXC_BAD_INSTRUCTION fault on the closing bracket of the trailing closure for the constraints.
As far as I can see, the NSTextView will be strongly retained by box, and so I'm at a loss to see the source of the error. The error shows up at the first line of ConstraintItem.init(target: AnyObject?, attributes: ConstraintAttributes). Per the instructions in the readme I'm posting here; can someone on the SnapKit team perhaps shed any additional light on the error? (The app works normally if I remove the box-related code.)
Added information:
The exception happens at line 37 of ConstraintItem.swift, which is self.target = target. I set a breakpoint right before that line and executed e target in the debugger; here's what I got:
(lldb) e target
(AnyObject?) $R1 = (instance_type = 0x0000608000164c80) {
instance_type = 0x0000608000164c80 {
AppKit.NSTextView = {
baseNSText#0 = <extracting data from value failed>
}
title = "some random text"
minimumWidth = 100
}
}
I found several answers.
How you search Google remains important. I varied my searches some more and came upon this here on SO, the short version of which is that it says you can't form a weak reference specifically to NSTextView and includes a link to explanatory Clang documentation.
Perhaps more interestingly, I also found the answer for "erratic" errors I mentioned in the title - one of the machines I develop on turns out to have Swift 3.1, but the other has 3.0.2. The more recent version does not exhibit the error forming the weak link, suggesting Apple has upgraded the NSTextView implementation.

Swift 2.2: Optional Binding in a function

Heys guys,
I am pretty new into programming and therefore I've followed I course on Udemy to teach me Swift 2.2.
For learning purpose I have been trying to program a BMI-calculator where I have a textfield (which just displays the value) and a slider where I can put my weight in kg. After dragging the slider the value is visible in the textfield. I cannot put a value into the textfield so that it is displayed on the slider!
The same textfield-slider relation is used with the height in cm. Now I created an IBAction the bring my kgSlider.value into my kgField.text and it looks like this:
#IBAction func kgSet(sender: AnyObject) {
kgField.text! = String(Int(kgSlider.value))
}
Thats works fine but I unwrapped (like the teacher in the course) without knowing, if there really is a value. Okay, I know in this case that there will be a value, but I would like to go more real and therefore I tried to use an Optional-Binding to find out, if there is a value instead of directly unwrap it.
Therefore I used the cm.Field and the cm.Slider in my code but it doesn't work for now and I don't know why. The code is the following:
#IBAction func cmSet(sender: AnyObject) {
if let tempCm = String(Int(cmSlider.value)) as String! {
cmField.text = tempCm
}
}
So I created the constant called tempCM which will got the value from the cmSlider, if there is a value. Therefore I casted the cmSlider.value like in the other IBAction into an Int and then into a String. If there is the value it will carry it into the cmField.text. This didn't work, therefore I tried to use the "as String!" statement but know I get always 0 instead of the correct value.
So what am I doing wrong there?
So, this should compile fine and provide you with your desired result.
#IBAction func cmSet(sender: AnyObject) {
if let tempCm = String(Int(cmSlider.value)) {
cmField.text = tempCm
}
}
You could also try this
cmField.text = String(Int(cmSlider.value)) ?? " "
in the second example, you are using the optional operator to say if you can convert this to an Int then that Int to a string set the cmField.text property to its value, otherwise use a blank space as the default value.

Saving data from two containerviews

First of all i wanne apologize for the code that will be used. I'am completely new to programming in general and it probably looks like .... :)
My problem is the following;
I have 1 ViewController (VC1) with 2 embedded container views (both TableViewControllers). Causs of the UI layout i want for my app i couldn't just use 1 TableVieController. Both of these container views have Textfields, labels, pickerviews that needs to be provided with data by the user.
Now i want to save all this data with 1 button from the VC1.
Everything displays without error but when i tap the save button is gives me the following error:
Could not cast value of type AddRaptorTableVCContainerOne' (0x1099ad840) to AddRaptorTableVCContainerTwo' (0x1099ad270).
Thanks in advance!
#IBAction func addRaptorSaveButton(sender: UIBarButtonItem) {
// Reference to childViewController
let childViewOne = childViewControllers.last as! AddRaptorTableVCContainerOne
let childViewTwo = childViewControllers.last as! AddRaptorTableVCContainerTwo
// Reference moc
let manObjCon = self.manObjCon
let addRaptorEntity = NSEntityDescription.entityForName("AddRaptorEntity", inManagedObjectContext: manObjCon!)
// Create instance of data model and initialize
var newRaptor = AddRaptorEntity(entity: addRaptorEntity!, insertIntoManagedObjectContext: manObjCon)
// Map our properties
newRaptor.image = UIImageJPEGRepresentation(self.addImageView.image, 1)
newRaptor.name = childViewOne.nameTextField.text
newRaptor.ringNo = childViewTwo.ringNoInputTextField.text
// Save our context
var error: NSError?
manObjCon!.save(nil)
println(newRaptor)
In two lines, you're saying that childViewControllers.last is two different things. Check whats actually in childViewControllers, using the debugger or by printing, and pick the right thing to cast as AddRaptorTableVCContainerTwo.