I have a WKInterfaceTable table view with a WKInterfaceButton.
How can I add a target action to the button from the table view. As there is no tag property I am not able to handle it.
If your WKInterfaceButton is contained within a row controller, here is one method to determine which row's button was tapped:
Add your WKInterfaceButton to the row controller and use interface builder to connect the button's action to your row controller class
Add a property to your row controller that allows you to reference your data (for example, a weak reference to your data or a tag)
Add a property to your row controller that allows you to set your interface controller as a delegate
Create a protocol for the delegate that allows you to pass the data reference
When initializing each row controller, be sure to set the data and delegate properties
When the button action is handled in the row controller, call the delegate method that you defined in your protocol. Something like:
- (void)rowController:(MyRowControllerClass *)rowController didSelectRowWithTag:(NSInteger)tag
Handle this delegate method in your interface controller to do whatever work is necessary.
I use this technique in my own Watch app, and it works very well.
Related
I have a PageViewController that has 3 child views contained within. I would like to see a simple Objective-C example using protocols/delegates for how I can trigger a method of the PageViewController when a user clicks a button in the child view controllers?
What you want is a simple delegation. You can create a page based project which will generate the code for you. After that create the protocol you want with its methods and add a delegate property to the Page child view controller. The only change you need to make is inside the pageViewController:viewControllerBeforeViewController and pageViewController:viewControllerAfterViewController methods. Before you return the page child controller there set also the delegate and implement the methods from the protocol.
Remember typical situation: we have UIButton, we have some event triggered by something (in our case let it be UITouchUpInside) AND some IBAction somewhere (for example in our UIViewController) that will be called when event occurs. IBAction is created by control-dragging from my button inside my view controller.
Now image another situation: I have some custom class, some event occurs inside it AND I want some IBAction to be performed when my custom event in my custom class occurs. To be more specific, I want to connect object to my view controller in storyboard, then control-drag from one of my events from created object to my view controller's IBAction (exactly like I did for UIButton and UITouchUpInside). In other words probably I need some kind of selector (?) to be set up from storyboard to call later.
The whole point of all it is to quickly drag from events in my custom class into another place to create (and later call) IBAction, so please do not mention delegation of any form.
I have the set up of a user clicking a UITableViewCell, this triggers a segue to a 'detail' view controller which is popped onto the stack.
First,
User Taps -> [myVC tableView didSelectRow...] - this is where I can work out which cell and therefore which model object my user wants to modify or access.
Second,
User Taps -> [myVC prepareForSegue...] - this is where I set up my detail view controller with the correct model object.
So, do I just store the selected model object in an instance variable between the two functions being called?
In prepareForSegue, the sender argument will be the cell, so you can work out which one was tapped at that point. You could also check the tableview's selectedIndexPath property.
You don't need to implement both functions.
I understand that you need to pass an instance of your model to your details view controller after you tap on a table view row. You have some ways to achieve that:
You can create a property in your view controller with a data type of your model. Let's name it for example firstObject. Then, inside didSelectRow you can set this property or update it according to your needs. Then, inside prepareForSegue you can pass this instance to your details view controller, by doing something like: detailsVC.detailsObject = firstObject.
Inside prepareForSegue, you can get the value of the current tapped table view row using indexPathForSelectedRow.row. Assuming that you have an array holding different objects of your model that you need them to be sent to your details view controller based on the tapped table view row index, you can do something like:
detailsVC.detailsObject = myObjectsArray[myTableView.indexPathForSelectedRow.row].
I hope that I was able to make it more clear for you.
Can this be done with the delegate method?
The reason I'm asking is because I have two buttons on the custom table cell. one deletes the cell and the other sends info from the table cell.m class into another view controller. How can I implement this properly?
Yes, you can setup a delegate relationship between a cell and the view controller, it follows the same structure and approach as a normal delegate relationship:
Create a protocol
Add a delegate property (weak)
Set the delegate when the cell is returned for display
nil the delegate when the cell is removed from display
Implement the delegate method(s) in the view controller
When you specify the delegate protocol methods, pass the pertinent information, something like:
- (void)tableCell:(UITableViewCell *)cell didTriggerButton:(UIButton *)sender;
with didTriggerButton set to an appropriate name for the purpose of the button. In this way the view controller can get the button if required and has access to the cell (so it can easily get the index path associated with it).
I have a UITableviewController and I push another UIViewController in 'didSelectRow..' method.
I have user input controls (combobox, stepper) in this viewController, that when the UIViewController is popped , I would like to receive the newly entered data in the UITableviewController (and update the tableview accordingly).
I saw some questions/answers, and some said to use "Delegation/Protocol" approach, but did not find any specific example how to achieve this.
Can someone help?
Create a new file for your project and choose the Protocol file type. (We'll call it CallBackProtocol.) In the view controller that you push, create a property that has a type of id<CallBackProtocol> delegate;. Have your table controller adopt the protocol and, when it creates the view controller, set controller.delegate = self;.
Define a method in the protocol that lets you pass whatever data you need back to the caller. Implement that method in the table controller and call it from the second view controller just before popping it.
(Or use a NSNotification.)