Error message when setting UICollectionView data source and delegate with custom class - swift

I am creating a sort of manual slideshow (i.e., the pictures move when the user taps a forward or backward button), and it is made with a Collection View. I had to create a custom collection cell view class, which I finished, but now I'm getting an error message in the iOS Simulator, "fatal error: unexpectedly found nil while unwrapping an Optional value" even though my code builds successfully. The error is in the ibCollectionView.dataSource = self line, and because I'm new to Swift and OOP (I learned about a month ago for the first time), I am confused by this error message, especially because there are no ? operators. I have included the problem part of my code (the part Xcode showed with the error message) below. Thank you!
import UIKit
class FluidIntakeMainMenuViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
//MARK: - Collection View Properties
#IBOutlet weak var ibCollectionView: UICollectionView!
#IBOutlet weak var ibCollectionViewLayout: UICollectionViewLayout!
var cellArray:[customCollectionViewCell] = Array(repeatElement(customCollectionViewCell(), count: 6))
let displayedCellDimensions = CGSize(width: 343, height: 248)
//MARK: - Xcode-generated Methods
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
ibCollectionView.dataSource = self
ibCollectionView.delegate = self
}
//My code for this class continues down here...

First and most important thing is to check the IBOutlet connection
that you made in your storyboard.
Try to remove the connection in storyboard and then reconnect it.
Secondly put a debugger on to check if it's still nil.
ibCollectionView.dataSource = self

I think you forgot about this:
override func viewDidLoad() {
super.viewDidLoad()
// Register cell classes
ibCollectionView?.register(YourCustomCell.self, forCellWithReuseIdentifier: "Cell")
And use "Cell" identifier in cellForItemAt...

Related

Cannot get the SceneView to appear on ViewController

I am brand new to Swift so please go easy on me!
I am basically having trouble with rendering an ARKIT ARSCNView with getting the error:
Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
Here is my code:
Initializing the view here by connecting to the Storyboard
#IBOutlet weak var sceneView: ARSCNView!
Here is the ViewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
setNeedsStatusBarAppearanceUpdate()
// crashes here
sceneView.delegate = self
}
Heres the ViewDidAppear:
override func viewDidAppear(_ animated: Bool) {
DispatchQueue.main.async {
self.animatePulsatingLayer()
self.dowloadModel()
}
}
The animatePulsatingLayer just plays an animation while the model is downloading.
The Download model just downloads the model to weak var node: SCNNode!
I have seen this code working before but since I have integrated SwiftUI into the project it has stopped working.
Any help would be appreciated.
This error mostly occurs when you remove or do not add the reference of the outlet with the .storyboard or .xib files.
I suggest you check them by right-clicking to the view on the storyboard and check if there is a connection.
Like this:
if there is no such connection you can simply connect them like this:

Setting and Saving UISwitch Value Error

My problem is that the UISwitch I have in my settings page keeps reverting to an off state once you leave the settings page meaning there is no way of using the switch properly. I did some searching around and found this question and answer:
How do i keep UISwitch state when changing ViewControllers?
I read this page and added the answer to my code:
#IBOutlet weak var NumSwitch: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
NumSwitch.isOn = UserDefaults.standard.bool(forKey: "switchState")
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func SaveSwitchPressed(_ sender: UISwitch) {
UserDefaults.standard.set(sender.isOn, forKey: "switchState")
}
However when I run this code I get:
Thread 1: EXC_BAD_INSTRUCTION(code=EXC_1386_INVOP,subcode=0x0)
(Highlighting the line: 'NumSwitch.isOn = UserDefaults.standard.bool(forKey: "switchState")')
[I am using Xcode 8.2.1]
I have connected two UIViewControllers to one ViewController Class so maybe that is causing the problem. I have tried many many other methods to make my switch work properly and this one seems to have worked for other people. Is there anything obvious that I am doing wrong?
[I would have liked to have added this as a comment on the aforementioned question but I do not have the reputation to do so]
If everything is hooked up to your outlets correctly then the following should work:
#IBOutlet weak var NumSwitch: UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
let isOn = UserDefaults.standard.bool(forKey: "switchState")
// If the below statement prints `nil` this is what's causing the crash
print(NumSwitch)
NumSwitch.setOn(isOn, animated: false)
}
#IBAction func SaveSwitchPressed(_ sender: UISwitch) {
UserDefaults.standard.set(sender.isOn, forKey: "switchState")
}
The error Thread 1: EXC_BAD_INSTRUCTION(code=EXC_1386_INVOP,subcode=0x0) usually means that you're trying to force unwrap an optional value. The only thing that could be causing that in your code is if NumSwitch is nil.
I'd also suggest not naming your properties with capital letters, as this can be misleading. Capitalised names are usually used to indicate declared types/classes/structs etc.

i am a new of swift coder ,and i cant include a class

class ViewController: UIViewController,UITextFieldDelegate {
#IBOutlet weak var text: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
name.delegate = self
// Do any additional setup after loading
}
these are some of my code
when name.delegate = self occured an error :
Use of unresolved identifier 'name'
i typed these code from book ,how to fixed it ?is the problem of swift grammar???
It should be:
text.delegate = self
because you add UITextFieldDelegate which need to conform a delegate of any UITextField you add in your code.
With that when you did something with your UITextField it will call its required delegate methods.
For more info refer this Apple Documentation on UITextFieldDelegate.

Storyboard UIView Objects Not Instantiating

I am working on a project with Swift and Storyboards. It's a conversion project from a traditional IB and Objective-C project. I am having an issue with a UITableView instantiating when the view is loaded. Let me explain.
The project is a navigation project. Here is an overview of the Storyboard.
The Storyboard's first viewController is HomeViewController and is a landing page that displays general info. The next VC is called FeedViewController shows a number of RSS feeds. You can see an expanded screen shot of the NavigationController, HomeViewController and FeedViewController in the picture below.
My problem is that I can't get the tableView to Instantiate. I first checked to make sure that my tableView was connected as an outlet and that the dataSource and delegate properties were connected. You can see this in the pic below.
In my FeedViewController class I have an Outler property called feedsTableView. You can see the declaration in the code below.
class FeedViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, FLODataHandlerDelegate
{
// View Contoller and Protocol Properties
var floView : FLOViewController?
var dataHandler : FLODataHandler?
// Interface and Content Properties
var refreshControl : UIRefreshControl?
// IBOutlets
#IBOutlet weak var feedsTableView: UITableView!
#IBOutlet weak var backgroundImage: UIImageView!
In the HomeViewController I have a FeedViewController property that I intend to use to gain access to FeedViewController's feedsTableView.
class HomeViewController: UIViewController, FLODataHandlerDelegate, MFMailComposeViewControllerDelegate
{
// View Contoller and Protocol Properties
var feedViewController : FeedViewController?
var dataHandler : FLODataHandler?
When HomeViewController's viewDidLoad() method is called I start the dataHandler - which instantiates the FeedViewController - and set it to my FeedViewController property.
override func viewDidLoad()
{
super.viewDidLoad()
// Set up the gesture recognizer to allow for swiping to the feed VC.
let recognizer = UISwipeGestureRecognizer(target: self, action: Selector("goToNext"))
recognizer.direction = UISwipeGestureRecognizerDirection.Left
self.view.addGestureRecognizer(recognizer)
// Start the data handler
self.setUpDataHandler()
}
setUpDataHandler()
func setUpDataHandler()
{
// Intitalize FeedVC for use later in the VC
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("FeedViewController") as! FeedViewController
self.feedViewController = vc
}
I also have a fail safe that if someone were to go to the FeedViewController before the setUpDataHandler() method is called then I instantiate FeedViewController here as well.
func goToNext()
{
// Grab the feedViewController so it can be pushed onto the stack. Make sure you set up the storyboard identifier.
let feedVC = self.storyboard!.instantiateViewControllerWithIdentifier("FeedViewController") as! FeedViewController
self.feedViewController = feedVC
self.navigationController!.pushViewController(self.feedViewController!, animated: true)
}
However the feedsTableView is not getting instantiated. In the viewDidLoad() method of FeedViewController I attempt to add the feedsTableView to a UIRefreshController.
override func viewDidLoad()
{
super.viewDidLoad()
self.refreshControl = UIRefreshControl()
self.refreshControl!.addTarget(self, action: "refreshInvoked:state:", forControlEvents: UIControlEvents.ValueChanged)
// See the note in viewDidLoad in FLOViewController.
self.feedsTableView.addSubview(self.refreshControl!)
}
When the app runs I get the following error.
fatal error: unexpectedly found nil while unwrapping an Optional value
The image below shows were this is called. It's the viewDidLoad() of the FeedViewController. As you can see in the picture I even tried instantiating the feedsTableView before adding it to the UIRefreshController and I still get the error.
Any help would be greatly appreciated.
Take care,
Jon
The reason why it doesn't work in the very last case, where you manually instantiate UITableView and assign that to self.feedsTableView, is that self.feedsTableView is declared weak. Thus, the table view comes into existence, is assigned, and vanishes in a puff of smoke because it has no memory management. By the time you get to the last line, self.feedsTableView is nil once again.
Thus, the solution for that last case is to remove the weak designation from your feedsTableView declaration.
That will get you past the crash in that last case. But of course you won't see anything because you are not also inserting the table view into your interface.

UILabel always unwrapping as nil when trying to change text value

I have a tableview with a list of sports and I want to open up the corresponding team page for each cell. In my team page I have a label which is suppose to change text depending on which cell you press from the list of sports. I passed the string from a segue correctly and my print lines show that the string is correct. However when I try to set the text of my label, there is an "unexpectedly found nil" error. My label is connected in IB correctly and is instantiated. It seems so simple but has been bugging me forever.
Here is my sport list controller segue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showTeamPage"{
let teamViewController: TeamPage = segue.destinationViewController as! TeamPage
teamViewController.teamSport = sport
}
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
And here is the TeamPage() code:
import UIKit
import Social
import CloudKit
class TeamPage: UITableViewController, UITableViewDelegate, UITableViewDataSource, UICollectionViewDelegate, UICollectionViewDataSource, UIAlertViewDelegate {
#IBOutlet weak var sportTitle: UILabel!
var teamSport: String!
override func viewDidLoad() {
super.viewDidLoad()
self.sportTitle = UILabel()
println(teamSport)
self.sportTitle.text = teamSport
println(sportTitle.text)
}
I'm going insane...
I think the compiler is confused because you're re-initializing the label. My guess is that when you made the call self.sportTitle = UILabel(), ARC kicks in to kill off the sportTitle UILabel! that you've made via a storyboard connection. And then, for some reason, self.sportTitle.text = teamSport tries to set the text of nil (since it's been destroyed due to your previous step).
To solve this, delete self.sportTitle = UILabel(). You don't need that.