0

I want to display my own custom view whenever the cell of the view controller's table view is tapped in my iOS app. And I also have to dismiss the custom view when an user taps a button put inside the custom view.

However, while I was able to display the custom view when the cell is tapped by an user, I cannot dismiss the custom view by tapping the button inside the custom view - it's crashed by the error: unrecognized selector sent to instance....

So I wonder what is the correct way to put the button inside the custom view and connect the @IBAction to it in order to dismiss it. Here's what I did:

  1. Add @IBAction connection between the custom view's .xib and its .swift file and call self.removeFromSuperview() from within the method - this makes the app crash with the error message above.

  2. Add @IBAction connection to my view controller that is called to display the custom view (i.e. one that has UITableView) - this cannot be done because when I tried to create the connection, the Xcode doesn't react to the control-drag behaviour.

Also, if I understand it correctly, I cannot add the custom view's xib to the storyboard file because the custom view is not created initially; it's instantiated by tapping the cell on runtime.

So how can I dismiss the custom view by tapping the button? Where should I write the code (i.e. in custom view's .swift file or the original VC's .swift file)?

UPDATE

When I added an @IBOutlet connection from the button on the custom view's xib to the custom view's .swift file, and tried to println() from within the view controller such as (println(customView.dismissButton)), then it also crashed due to the error: this class is not key value coding-compliant for the key dismissButton.. So I might be better off to just add the gesture controller and make any taps on the window react to dismiss the custom view... It's pretty disgusting.

UPDATE 2

@Caroline's zip file in the comment section is exactly what I wanted to do, but instead of creating and instantiating the custom view all from within code, I want to create the UI on xib, create a @IBAction connection between the components on the xib and my code, and finally unarchives it from within code to use.

Blaszard
  • 30,954
  • 51
  • 153
  • 233

3 Answers3

3

Today, you should almost certainly be using a container view for this.

Then it is trivial to hide it, animate it, slide it around, send messages to it - whatever.

https://stackoverflow.com/a/23403979/294884

"Thanks. But do I have to use another view controller just in order to do it?"

Yes, of course. You should definitely use a container view. It's the only way to go for years now. Just drag one on in Storyboard.

Pretty much everything is a container view in iOS now. Every little thing. It's "the" paradigm of the day.

Community
  • 1
  • 1
Fattie
  • 27,874
  • 70
  • 431
  • 719
  • `Then it is trivial to hide it, animate it, slide it around, send messages to it - whatever.` Do you know any good tutorials on this? – Blaszard Sep 30 '14 at 00:24
  • Hmm! Good question! I'll look around – Fattie Sep 30 '14 at 06:12
  • I've been searching for it on the Web, but there are very few tutorials on it. Also, most of iOS books don't even mention it. What I find interesting is O'reilly's [Programming iOS8](http://shop.oreilly.com/product/0636920034261.do), which explains the container view pretty deeply (both in code and storyboard, in Chapter 6) and I've been reading right now. – Blaszard Sep 30 '14 at 06:24
1

You could put your custom view inside a view controller and use segues to load the custom view.

This means that you could have your custom view in the storyboard (under its new view controller), and have a segue from the table view cell to the new view controller, and an unwind segue from the new view controller to the original view controller.

This is an Objective-C tutorial, but may help with the Storyboard concepts:

http://www.raywenderlich.com/50308/storyboards-tutorial-in-ios-7-part-1

Edit:

Depending on what the view is actually doing, the normal way to bring up views for a UITableViewCell detail is to have the detail view inside a separate view controller and link via a segue.

I don't really know why your app is crashing with your code - it really depends on how the Storyboard is set up. If you were to do it in code, you could do it something like this:

class ViewController: UIViewController {

  var greenView = UIView(frame: CGRect(x:100,y:500,width:200,height:200))
  var greenButton = UIButton(frame: CGRectMake(20, 20, 80, 40))

  override func viewDidLoad() {
    super.viewDidLoad()
    greenView.backgroundColor = UIColor.greenColor()
    greenView.addSubview(greenButton)
    greenButton.setTitle("Close Me", forState: .Normal)
    greenButton.addTarget(self, action: "hideGreenView", forControlEvents: .TouchUpInside)
  }

  func hideGreenView() {
    self.greenView.removeFromSuperview()
  }

  @IBAction func greenview(sender: AnyObject) {
    self.view.addSubview(greenView)
  }

}

That code assumes you have a button linked to greenview() on your storyboard, but the rest of it isn't on the storyboard.

You also course create the view on the storyboard, and have it as a hidden view, and then in the functions hide or unhide. If you want to animate the view into position, you could do that with UIView animations.

You also may be having a problem if your UIViewController is a UITableViewController. You could have a UITableView inside a UIViewController with the UIViewController being the delegate and datasource, but this seems like "smelly" code to me (depending on what you are actually trying to achieve, of course).

Caroline
  • 4,875
  • 2
  • 31
  • 47
  • Thanks. But do I have to use another view controller just in order to do it? – Blaszard Sep 20 '14 at 06:57
  • Edited for an example of adding and removing a view via a button (however, this example isn't from a UITableViewCell, which may be your problem) – Caroline Sep 20 '14 at 07:59
  • Yeah, I tried to do what you wrote in code, but Xcode doesn't allow me to create `@IBAction` connection (check out the second list on my original post). I haven't used it as a hidden view though. – Blaszard Sep 20 '14 at 10:59
  • If you are adding buttons to a UITableViewCell, then you have to have that button connected to an @IBAction in a class associated with a UITableViewCell. You can't attach a button in a cell to your UITableViewController, because there are in memory as many buttons as there are cells. – Caroline Sep 20 '14 at 11:24
  • No, I don't want to add a button to `UITableViewCell`. I want to show a custom view and on which I put a button. And the custom view is displayed whenever an user taps the `UITableViewCell` in the original view controller, and dismissed whenever the user taps the button on the custom view that is displayed. – Blaszard Sep 20 '14 at 11:31
  • Like this? Putting a view on top of a table view is not something I would generally like to do: https://www.dropbox.com/s/7t1m1g2y3jjjuh8/Gardecolo.zip?dl=0 (Sorry to be a bit dense - I don't really know what you're trying to do). – Caroline Sep 20 '14 at 11:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/61598/discussion-between-caroline-and-gardecolo). – Caroline Sep 20 '14 at 11:51
-1

Tested this code using XCode 8 and Swift 3

To Add Custom View to SuperView use:

self.view.addSubview(myView)

To Remove Custom View from Superview use:

self.view.willRemoveSubview(myView)

Pravin Kamble
  • 849
  • 8
  • 12