I'm trying to build to-do app using Xcode 6 and Swift. I was able to run the app on Xcode 6 dp2 but after updating to dp7 I'm getting this error:
'bool' is not convertible to 'uint8'.
Here is the function with the error:
override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
**if ((segue && segue!.identifier == "showdetails") != nil)**{
var selectedIndexPath:NSIndexPath = self.tableView.indexPathForSelectedRow()
var detailViewController:DetailViewController = segue!.destinationViewController as DetailViewController
detailViewController.toDoData = toDoItems.objectAtIndex(selectedIndexPath.row) as NSDictionary
}
}
The correct way to write that is:
if (segue != nil && segue!.identifier == "showdetails") {
but an even better way is using optional binding:
if let segue = segue {
if (segue.identifier == "showdetails") {
Note that there are other errors about incorrect usage of optionals. This is the modified code that compiles in playground:
if let segue = segue {
if (segue.identifier == "showdetails") {
var selectedIndexPath:NSIndexPath? = self.tableView.indexPathForSelectedRow()
if let selectedIndexPath = selectedIndexPath {
var detailViewController:DetailViewController = segue.destinationViewController as DetailViewController
detailViewController.toDoData = toDoItems.objectAtIndex(selectedIndexPath.row) as NSDictionary
}
}
}
indexPathForSelectedRow returns an optional, so you have to account for that.
Update: as pointed out by #MartinR, segue is no longer optional, so you can solve the problem by simply updating the function signature, and its implementation should look like:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "showdetails") {
var selectedIndexPath = self.tableView.indexPathForSelectedRow()
if let selectedIndexPath = selectedIndexPath {
var detailViewController = segue.destinationViewController as DetailViewController
detailViewController.toDoData = toDoItems.objectAtIndex(selectedIndexPath.row) as NSDictionary
}
}
}
First of all when I read the documentation what I read is :
func prepareForSegue(_ segue: UIStoryboardSegue, sender sender: AnyObject?)
UIKit seems to be updated in Beta7 to use less optionals. So segue may be not optional.
Then even if your function signature is good, you are comparing a Boolean to nil.
This (segue && segue!.identifier == "showdetails") is a boolean. A boolean is either true or false.
And at the very end, here is the best practice to unwrap a variable :
if let mySafeVariable = myOptionalVariable {
if mySafeVariable.attribute == <Whatever> {
}
}
You should. No, wait, you must read the Swift free iBooks.
Related
my code before the migation to Swift 2.0:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "RhymeFavoriten") {
// pass data to next view
let dest = segue.destinationViewController as! FavoritenViewController
let source = segue.sourceViewController as! RhymeViewController // !!!!!!
dest.favoritenType = 1
dest.delegate = self
}
}
the migration told me to change it to
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "RhymeFavoriten") {
// pass data to next view
let dest = segue.destinationViewController as! FavoritenViewController
_ = segue.sourceViewController as! RhymeViewController // !!!!!!!!!!
dest.favoritenType = 1
dest.delegate = self
}
or
func textSelected(selectedText:String, selectedType:Int) {
var fullTextArr = text.componentsSeparatedByString("\n")
var myArray = [String]() // !!!!!!
to
func textSelected(selectedText:String, selectedType:Int) {
var fullTextArr = text.componentsSeparatedByString("\n")
_ = [String]() // !!!!!!!!!
I canĀ“t see, what is _ = standing for :-(
_ is a placeholder. It means that the values assigned to _ are ignored.
Xcode's migration tool made this changes because it has detected that you didn't use source or myArray anywhere, thus replaced these variables by the placeholder.
Now instead of being assigned to a variable, the returning result of segue.sourceViewController as! RhymeViewController and the returning result of [String]() are ignored.
The returning result is ignored but the expression is still evaluated at runtime: if it has side effects, these effects will occur.
So if you actually don't need these instructions you should get rid of them entirely.
This is my code and it's not working. LightOrDark and LightDark are Integers and should be equal when the app changes views.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "LightSegue") {
if let MinigameView = segue.destinationViewController as? MinigameView {
self.LightOrDark = MinigameView.LightDark
}
}
}
self.LightOrDark = MinigameView.LightDark this statement sets MinigameView.LightDark to current class's LightOrDark.
You need to set LightDark of MinigameView so your code should be like,
MinigameView.LightDark = self.LightOrDark
And you should follow naming standard. variable or instance name should be start with lower case not upper case.
so your instance name should be lightOrDark and minigameView instead of LightOrDark and MinigameView.
Hope this will help :)
You need to set the destination viewcontroller property
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
guard let destVc = segue.destinationViewController as? MinigameView else {
return
}
destVc.LightOrDark = self.LightDark
}}
This is wrong: self.LightOrDark = MinigameView.LightDark. Change it to:
MinigameView.LightDark = self.LightOrDark
I have a managedObject that is being passed from 1 view controller to another the first pass works fine but when I try to pass the next object after the relationship has been set it doesn't send anything and comes back as either nil or if I try to use other methods comes back with a syntax error. The code I am using for the view controllers is as follows
View Controller 1, The first object set:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let identifier = segue.identifier {
switch identifier {
case "popOver":
if let VC = segue.destinationViewController as? ClassDeckNameViewController
{
if let ppc = VC.popoverPresentationController {
VC.modalPresentationStyle = UIModalPresentationStyle.Popover
ppc.permittedArrowDirections = UIPopoverArrowDirection.Any
ppc.delegate = self
}
VC.classSave = (sender as! ClassSelection)
}
default: break
}
}
}
#IBAction func buttonPriest(sender: AnyObject) {
let entity = NSEntityDescription.entityForName("ClassSelection", inManagedObjectContext: classMOC!)
let newObject = ClassSelection(entity: entity!,insertIntoManagedObjectContext: classMOC)
newObject.classname = "Priest"
var error: NSError?
if let err = error {
println(err)
} else {
classMOC?.save(&error)
self.performSegueWithIdentifier("popOver", sender: newObject)
}
}
This passes the object without problem to the second view controller but this is the one that won't pass any further to the final presenting controller offering the user the final selections for their "Deck":
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showCardSelection" {
let detailVC: CardSelectionViewController = segue.destinationViewController as! CardSelectionViewController
detailVC.passedDeckObject = (sender as! Deck)
}
}
#IBAction func enterButton(sender: AnyObject) {
let entityDescription = NSEntityDescription.entityForName("Deck",inManagedObjectContext: managedObjectContext!)
let storeDeck = Deck(entity: entityDescription!,insertIntoManagedObjectContext: managedObjectContext)
storeDeck.deckname = usersDeckName.text
storeDeck.classSelected = classSave!
var error: NSError?
managedObjectContext?.save(&error)
if let err = error {
status.text = err.localizedFailureReason
} else {
usersDeckName.text = ""
status.text = "Deck Saved"
self.performSegueWithIdentifier("showCardSelection", sender: storeDeck)
}
}
I made passedDeckObject a variable of type Deck? in the final view controller to set the final relationship methods I know I am doing something wrong but I am unsure what! Any help with this would be amazing!
This looks to be a misconfiguration issue where the segue is being triggered directly in the storyboard rather than calling your code. As such the sender is a button rather than the new entity instance you're expecting.
To fix, disconnect the segue in the storyboard and connect (if it isn't already) the button to your action method in the view controller.
I'm trying to write prepareForSegue in SWRevealViewController with Swift.
Here is my code:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!)
{
if(segue!.identifier == "segueName")
{
var someText = "Text"
var rvc:newViewController = segue!.destinationViewController as newViewController
rvc.topText = someText
}
}
In newViewController I have topText as NSString
Of course I got nil text because I should make SWRevealViewControllerSegue but I don't know how it should look in Swift
I've found the solution.
First of all need to configure SWRevealControllerSegue. In swift it should looks like:
if(segue.isKindOfClass(SWRevealViewControllerSegue))
{
var rvcs: SWRevealViewControllerSegue = segue as SWRevealViewControllerSegue
var rvc:SWRevealViewController = self.revealViewController()
rvcs.performBlock = {(rvc_segue, svc, dvc) in
var nc:UINavigationController = dvc as UINavigationController
rvc.pushFrontViewController(nc, animated: true)
}
}
Second. XCode beta works bad right now with IBOutlet and segue like this. With variable everything is ok.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.isKindOfClass(SWRevealViewControllerSegue))
{
var rvcs: SWRevealViewControllerSegue = segue as SWRevealViewControllerSegue
var rvc:SWRevealViewController = self.revealViewController()
rvcs.performBlock = {(rvc_segue, svc, dvc) in
var nc:UINavigationController = self.revealViewController().frontViewController as UINavigationController
nc.setViewControllers([dvc], animated: true)
self.revealViewController().setFrontViewPosition(FrontViewPositionLeft, animated: true)
}
}
}
This doesn't work with the latest version. The release notes state:
Took a cleaner approach to storyboard support. SWRevealViewControllerSegue is now deprecated and you should use SWRevealViewControllerSegueSetController and SWRevealViewControllerSeguePushController instead.
There aren't any swift examples anywhere I can find that explain this though.
The performBlock method no longer exists.
Appreciate any help. It seems impossible to do swift without first learning objective c at the moment :)
What was newViewController? This should work:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!)
{
if(segue.identifier == "segueName")
{
let someText = "Text"
let rvc = segue.destinationViewController as SWRevealViewController
rvc.topText = someText
}
}
So I'm writing this segue method in Swift, but when I unwrap controller, it is always none. Without the as? it just downright fails at runtime. Whats going on?
override func prepareForSegue(segue : UIStoryboardSegue!, sender: AnyObject!) {
if(segue.identifier == "showCoursesSegue") {
var controller = segue.destinationViewController as? EditViewController
controller!.test = true
}
}
This works fine for me in prepare for segue. Tried actually setting the type of controller to EditViewController and removing that ?.
var dst: NoteViewController = segue.destinationViewController as NoteViewController
Do it the Swift way!
func prepareForSegue(segue : UIStoryboardSegue!, sender: AnyObject!) {
switch segue.identifier! {
case "showCoursesSegue":
switch segue.destinationViewController {
case let controller as EditViewController:
controller.test = true
default:
println("segue.destinationViewController is \(segue.destinationViewController)")
}
default:
println("segue.identifier is \(segue.identifier)")
}
}
The issue here was that in IB, the ViewController hadn't been set up as a custom class. I'd post a picture but haven't got enough rep.