'override' can only be specified on class members - xcode6

I'm getting an error message in relation to an 'override func'. It seems to be saying that 'viewWillAppear' is not a class member.
Can anyone tell me how I would fix this?
import UIKit
import AVFoundation
import CoreData
class SoundListViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var audioPlayer = AVAudioPlayer()
var sounds: [Sound] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.dataSource = self
self.tableView.delegate = self
override func viewWillAppear(animated: Bool) { // 'override' can only be specified on class members
self.tableView.reloadData()
}
}

Related

Xib not showing up in view

I have a Xib file trying to set it up with my storyboard. Everything in the Xib file is fine, but for some reason, it's not showing. I imported a file from GitHub which is set to my Xib, it's in Objective-C and I set the bridging, no errors. But when I run it nothing shows its blank. Did I not set something in the View Controller? Everything is done programmatically and I just set the class in storyboard.
Screenshot of storyboard:
What the simulator gives me when I push to the ViewController:
This is what I'm supposed to see:
What I am trying to implement -
https://github.com/jberlana/JBCroppableView
My XIB class
import UIKit
class CropViewXIB: UIView {
#IBOutlet weak var ImageView: JBCroppableImageView!
#IBAction func SubAction(_ sender: Any) {
ImageView.removePoint()
}
#IBAction func AddAction(_ sender: Any) {
ImageView.addPoint()
}
#IBAction func UndoAction(_ sender: Any) {
ImageView.reverseCrop()
}
#IBAction func CropAction(_ sender: Any) {
ImageView.crop()
}
override init(frame: CGRect) {
super.init(frame: frame)
commomInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commomInit()
}
private func commomInit(){
Bundle.main.loadNibNamed("CropViewXIB", owner: self, options: nil)
self.addSubview(ImageView)
ImageView.frame = self.bounds
ImageView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
}
}
my view controller
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var cropView: CropViewXIB!
override func viewDidLoad() {
super.viewDidLoad()
}
}
The issue is that you didn't actually get the parent view for your UINib object.
Bundle.main.loadNibNamed("CropViewXIB", owner: self, options: nil)
The line above returns an [Any] in your case you aren't even using the view that it is returning. so the idea is to get the first object from it and cast it as UIView such as:
Bundle.main.loadNibNamed("CropViewXIB", owner: self, options: nil)?.first as? UIView
Personally this is how I interact with a Nib. I create a view property of type UIView that can be referred as the parent view for the nib, and all subviews get added to it instead of self.
Something like this:
final class SomeNibView: UIView {
public var view: UIView!
private func setup() { // called to the initializer
// grab the views from loadNibNamed
guard let _view = Bundle.main.loadNibNamed("name", owner: self, options: nil)?.first as? UIView else { return }
// set it to our view property
view = _view
// add this property to the nib subview aka self
addSubview(view)
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
private func addMulitpleSubviews() {
// instead of doing self.addSubview(....) when it comes to add other subviews
// you'll do this view.addSubview(....)
}
}
Try to load xib using programming not using storyboard.
override func viewDidLoad()
{
super.viewDidLoad()
guard let yourXIB = Bundle.main.loadNibNamed("CropViewXIB", owner: self, options: nil)?.first as? CropViewXIB else { return}
self.view.addSubview(yourXIB)
}

I can't use touchesBegan/Moved/Ended and a UITapGestureRecognizer

Is it not possible to use both of these at the same time. Originally, I have overriden (Swift) touchesBegan/Moved/Ended in my ViewController.
Now, I'm wanting to add a TapGestureRecognizer to certain views under a certain situation, but the selector/action never gets fired.
class ViewController: UIViewController, UIGestureRecognizerDelegate {
...
func addTapGesturesOnNumberPadDisplay() {
if tapGestureRecognizerNumberPadView == nil {
tapGestureRecognizerNumberPadView = UITapGestureRecognizer(target: self, action: "handleTap:")
tapGestureRecognizerNumberPadView!.delegate = self
self.numberViewDone?.addGestureRecognizer(tapGestureRecognizerNumberPadView!)
}
}
...
func handleTap(sender: UITapGestureRecognizer) {
//never hit
Is this not possible? Should I just implement my own tapping ability in touchesBegan since I'm overriding it anyway, or is there a way to also use a tapGestureRecognizer here?
Since you have overriden touchesBegan/Moved/Ended in viewcontroller it should not have any impact on tap gestures in other subviews. Ideally it should work. Please check code below, works as expected.
class ViewController: UIViewController, UIGestureRecognizerDelegate {
#IBOutlet weak var categoryScrollView: UIScrollView!
var customView: UIView!
var tapGestureRecognizerNumberPadView : UITapGestureRecognizer?
override func viewDidLoad() {
super.viewDidLoad()
customView = UIView()
customView.frame.origin = CGPointMake(50,50)
customView.frame.size = CGSizeMake(100, 100)
customView.backgroundColor = UIColor.blueColor()
self.view.addSubview(customView)
addTapGesturesOnNumberPadDisplay()
}
func addTapGesturesOnNumberPadDisplay() {
if tapGestureRecognizerNumberPadView == nil {
tapGestureRecognizerNumberPadView = UITapGestureRecognizer(target: self, action: "handleTap:")
tapGestureRecognizerNumberPadView!.delegate = self
self.customView?.addGestureRecognizer(tapGestureRecognizerNumberPadView!)
}
}
func handleTap(sender: UITapGestureRecognizer) {
print("handleTap")
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
}
}
Please check is there any other gestures to 'numberViewDone' view.

Segue on DidSelectRowAtIndexPath from Custom DataSource/Delegate Swift

My setup:
`UITableViewController` (ComboViewController)
-> Several Static Cells
-> One Static Cell contains a dynamic `tableView`
I need to use a custom Delegate/DataSource because the dynamic tableView is embedded in the Static TableView within the TableViewController
This custom Delegate/DataSource looks like this:
class DataSource: NSObject, UITableViewDataSource, UITableViewDelegate {
// class variables
override init() {
super.init()
// initialize variables
}
//some data source/ delegate methods like number of rows, cellForRowAtIndexPath
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var indexedCombos: NSDictionary?
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let comboVC: ComboInfoViewController = storyboard.instantiateViewControllerWithIdentifier("ComboInfo") as! ComboInfoViewController
comboVC.doSegue()
}
}
Within ComboViewController I have this:
class ComboInfoViewController: UITableViewController {
func doSegue() {
self.performSegueWithIdentifier("tosingle", sender: combListTable)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "tosingle" {
//do stuff
}
}
}
If the segue is modal I get this error:
Warning: Attempt to present SingleProductViewController on ComboInfoViewController whose view is not in the window hierarchy!
If the segue is push, then the prepareForSegue method gets called, but the viewController does not push! What is happening?
I've searched and searched. But I have no idea what could be resulting in this behavior.
When you create the ComboInfoViewController instance with this line,
let comboVC: ComboInfoViewController = storyboard.instantiateViewControllerWithIdentifier("ComboInfo") as! ComboInfoViewController
You're creating a new instance that is not the one you have on screen, and never will be, so that's why you get the error. It is very important that you understand this concept; understanding how view controllers are created, and how to get pointers to ones that already exist is fundamental to iOS programming.
However, in this case you don't even need to get a pointer to the one on screen, because you should connect the segue directly from the cell (the dynamic prototype), which means you won't need any code to execute it. You can delete the didSelectRowAtIndexPath method, and the doSegue method. You only need to implement prepareForSegue. If you need to pass information to the next controller based one which row was touched, you can do it like below. The table view controller code should now look like this (this is an update of the code in my answer to this question, Swift: TableView within Static UITableViewCell),
class ComboInfoViewController: UITableViewController {
#IBOutlet weak var staticTableView: UITableView!
#IBOutlet weak var dynamicTableView: UITableView!
var dataSource = DataSource()
override func viewDidLoad() {
super.viewDidLoad()
dynamicTableView.dataSource = dataSource
dynamicTableView.delegate = dataSource
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row != 1 {
return 44
}else{
return 250 // the second cell has the dynamic table view in it
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "tosingle" {
var cell = sender as! UITableViewCell
var indexPath = dynamicTableView.indexPathForCell(cell)
var dataPoint = dataSource.theData[indexPath!.row] // theData is the array used to populate the dynamic table view in the DataSource class
// pass dataPoint to the next view controller which you get from segue.destinationviewController
println(dataPoint)
}
}
}

How do i refer to a variable that was made in another view controller in swift

How do i add the text to from my textfield into an array that is made in another ViewController.
class FirstViewController: UIViewController, UITableViewDelegate {
var thingsToDo = []
class SecondViewController: UIViewController {
#IBOutlet weak var enterTask: UITextField!
#IBAction func addtask(sender: AnyObject) {
thingsToDo += enterTask.text
}
You can use the prepareForSegue-method to pass objects to another viewcontroller. First you have to add global variable in your SecondViewController.
var theThingsToDo:[AnyObject]!
Then, in your FirstViewController, you can use the prepareForSegue-method and pass the value from your FirstViewController to your SecondViewController. It is important that you set the name of the segue in your Storyboard.
You can find the segue-identifier in the top right corner of Xcode:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if segue.identifier == "yourSegueIdentifier" {
// Value of the FirstViewControllers variable 'thingsToDo' will be sent to the SecondViewController
(segue.destinationViewController as SecondViewController).theThingsToDo = thingsToDo
}
}
#IBAction func addtask(sender: AnyObject) {
theThingsToDo += enterTask.text
}

UITableView and UITableViewCell Swift

I am working with Swift and am having a problem loading saved data into UITableView custom cell. I have created a ViewController/ TableViewController and TableViewCell. The form data is saving and is displayed in console. The problem is, nothing gets returned when going back to TableView (My list). I have created labels in the custom cell and everything seems to be linked correctly, but nothing is being displayed.. Am I missing something?
Here is the code from my ViewController:
import UIKit
import CoreData
class DetailsViewController: UIViewController, UITextFieldDelegate, UITextViewDelegate {
var cell:UITableViewCell?
#IBOutlet var txtPTitle: UITextField!
#IBOutlet var txtPDesc: UITextField!
#IBOutlet var txtSDate: UITextField!
#IBOutlet var txtEDate: UITextField!
// Add our date picker keyboard on Project Start Date
#IBAction func dp(sender: UITextField!) {
var datePickerView : UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerView
datePickerView.addTarget(self, action: Selector("handleDatePicker:"), forControlEvents: UIControlEvents.ValueChanged)
}
func handleDatePicker(sender: UIDatePicker) {
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMM dd yyyy"
txtSDate.text = dateFormatter.stringFromDate(sender.date)
}
#IBAction func dp2(sender: UITextField!) {
var datePickerView : UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerView
datePickerView.addTarget(self, action: Selector("handleDatePicker2:"), forControlEvents: UIControlEvents.ValueChanged)
}
func handleDatePicker2(sender: UIDatePicker) {
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMM dd yyyy"
txtEDate.text = dateFormatter.stringFromDate(sender.date)
}
var project: String = ""
var desc: String = ""
var sdate: String = ""
var edate: String = ""
var existingItem: NSManagedObject!
override func viewDidLoad() {
super.viewDidLoad()
if (existingItem != nil) {
txtPTitle.text = project
txtPDesc.text = desc
txtSDate.text = sdate
txtEDate.text = edate
}
//Do any additional setup after loading the view.
txtPTitle.delegate = self
txtPDesc.delegate = self
txtSDate.delegate = self
txtEDate.delegate = self
}
func textFieldShouldReturn(textField: UITextField!) -> Bool {
textField.resignFirstResponder()
txtPDesc.resignFirstResponder()
return true
}
override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
self.view.endEditing(true)
}
#IBAction func savedTapped(sender: AnyObject) {
// Reference to our app delegate
let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
// Reference moc
let contxt: NSManagedObjectContext = appDel.managedObjectContext!
let en = NSEntityDescription.entityForName("ProjectTask", inManagedObjectContext: contxt)
// Check if task exists
if (existingItem != nil) {
existingItem.setValue(txtPTitle.text as String, forKey: "project")
existingItem.setValue(txtPDesc.text as String, forKey: "desc")
existingItem.setValue(txtSDate.text as String, forKey: "sdate")
existingItem.setValue(txtEDate.text as String, forKey: "edate")
} else {
// Create instance of our data model and initialize
var newItem = Model(entity: en, insertIntoManagedObjectContext: contxt)
// Map our properties
newItem.project = txtPTitle.text
newItem.desc = txtPDesc.text
newItem.sdate = txtSDate.text
newItem.edate = txtEDate.text
println(newItem)
}
// Save our context
contxt.save(nil)
// Navigate back to root view controller
self.navigationController.popToRootViewControllerAnimated(true)
}
#IBAction func cancel(sender: AnyObject) {
// Navigate back to root view controller
self.navigationController.popToRootViewControllerAnimated(true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Here is the code from my TableViewController:
import UIKit
import CoreData
class ListTableViewController: UITableViewController, UITableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
//Register Our Custom Table Cell //
self.tableView.registerClass(ProjectTableViewCell.self, forCellReuseIdentifier: "projectlist")
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell = tableView.dequeueReusableCellWithIdentifier("projectlist", forIndexPath: indexPath) as ProjectTableViewCell
cell.projectLabel.text = "project"
return cell
}
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return 0
}
Here is the code from the TableViewCell
import UIKit
import CoreData
class ProjectTableViewCell: UITableViewCell {
#IBOutlet var projectLabel: UILabel! = UILabel()
#IBOutlet var descriptionLabel: UILabel! = UILabel()
#IBOutlet var sdateLabel: UILabel! = UILabel()
#IBOutlet var edateLabel: UILabel! = UILabel()
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
I also have another for NSManagedObject
import UIKit
import CoreData
#objc(Model)
class Model: NSManagedObject {
//Properties feed of attributes on our database - Must match the database attributes
#NSManaged var project: String
#NSManaged var desc: String
#NSManaged var sdate: String
#NSManaged var edate: String
}
Is there something I am missing here? This is driving me crazy. I read that this should be added to the tableviewcell, but I keep getting error this error: tableviewcell does not implement its superclass's required members
init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: UITableViewCellStyle.Value1, reuseIdentifier: reuseIdentifier)
}
Your problem is that you're registering the class -- you should only do that if you create the cell entirely in code (that is, the subviews are created programmatically). If you made the cell in the storyboard, don't register anything. If you made it in a xib, then register the nib. All those lines like,
#IBOutlet var projectLabel: UILabel! = UILabel()
don't make sense. You're creating a new label with no frame, but I assume you already created theses labels in IB somewhere (since you're using IBOutlets). If you did create them in IB, then those lines should be like so,
#IBOutlet var projectLabel: UILabel!
Please replace your init in TableViewCell class with following -
required init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)
}