UITableView Header Selection - iphone

Can anyone explain me how can I detect a selection in a table view Header view like in tableView:didSelectRowAtIndexPath: ? It would be very useful for me. I've defined the header as UITableCellView so I could attach a UISwitch as an accessory view, and it worked great but now I can't detect the changes made in the switch. Any suggestions?

I'm going to assume you're dynamically creating the switches, not creating them in IB. If that's the case, you'll need to do two things to receive and distinguish changes to your switches. First, when you create the switch, set its tag property to some value that represents the corresponding section (like maybe the section index itself). Then, add an event handler to the switch that will call back to a method on your view controller.
So, in tableView:viewForHeaderInSection:, lazily instantiate your header view, maybe caching it, then say something like:
[switch setTag:section];
And add the event handler thusly, where switchToggled: is defined just as any other IBAction would be:
[switch addTarget:self
action:#selector(switchToggled:)
forControlEvents:UIControlEventValueChanged];
Then, just cast the sender you receive in your event handler to UISwitch *, and use the tag property to tell which switch was toggled.

Related

iOS Custom Control

I am building a custom control that looks like the one in the image below.
It will basically be a menu with a slider. The arrows will allow me to change the three days show on the slider track. Acoording to the day I select with the slider I want to change some views on the main screen (this menu will on the bottom of my page). So basically this is the only thing that I will "listen" in my main controller: if some day has been selected.
I have figured out all the code I will have to write, but I am not sure wether I should subclass UIControl or UIView. And if so, where should I write the code of my controller (changing the days, adding the drag effec, etc ) in the UIControl (UIView)? Or should I subclass UIViewController, and write there all the code there. (but if so, why should I subclass UIControl (UIView) in the first way).
So basically I want to know what extra files I need to create, besides the view interface of my custom control(which I did in the IB), where should I put the code (IBOutlets, IBAction methods) and how do I communicate with the main view controller (I set the main controller as a delegate of my custom control?).
Sorry for the long post.
Thanks
I recommend to subclass UIControl. Users of this control can do [yourControl addTarget:self action:#selector(someMethod:) forControlEvents:UIControlValueChanged]; to react to changed values. In your control, when you have determined that a new day has been selected, you call [self sendActionsForControlsEvents:UIControlValueChanged]; and voila, all interested classes will get informed.
Keep that control as self-contained as possible. This means, only give it as much logic as you need to, and nothing more. Think about how you use Apple provided UI elements: try to make yours as generic (if practical; use common sense here). In short: you should thrive to make this control generic enough that it could be useful to you in other projects or other places of your app.
The short answer is you should subclass UIControl and put all of the logic to draw the component and interact with the component there. UIControl inherits from UIView and adds target/action behavior. This way you can sendAction:to:forEvents: with UIControlEventValueChanged whenever the date changes.
You could alternatively implement a delegate protocol for when the user changes the selected date.
For example:
#protocol DateSliderDelegate <NSObject>
- (void)dateSlider:(id)slider dateDidChange:(NSDate *)date fromDate:(NSDate *)oldDate;
#end
You don't want to use a UIViewController since it's job is to manage higher-level views, like the screen that your widget is on. You'll use a view controller later when you are consuming your component and do things like set the date to display initially and listen for change events.

Raise selection event (didSelectRowAtIndexPath) when subview of UITableViewCell is tapped

I've created a custom UITableViewCell that includes a number of subviews. In most cases I want the controller for the UITableViewCell to handle the events. In one case I want the subview to simply pass on the event to the parent UITableViewCell which will cause it to invoke didSelectRowAtIndexPath on the assigned delegate.
To put it another way: I want the subview to become "event transparent" -- I want events to pass over / through it and register with the underlying cell.
Any suggestions? In other languages I would raise an event. New to Objective-C and Cocoa and haven't been able to google up an answer yet.
Thanks in advance.
Try setting your view's userInteractionEnabled property to NO.
This will make it ignore all touch events, and then the views under it will be able to catch these events.
A couple of ways come to my mind:
I believe the translation for "raise an event" would be to send a notification, in which case you could look into NSNotification and NSNotificationCenter. Pretty simple.
Optionally, you could add a reference to an object that follows the UITableViewDelegate protocol to each cell, and when creating the cell, assigning that reference to the object that you want to handle that event, when the subview is tapped, send the didSelectRowAtIndexPath message to that reference.
Personally I'd choose the second one, because I'm not a big fan of notifications.

iphone - getting the button id in a segmented control

I am trying to create something that uses the idea of the UIPopOverController, I mean, have that speech bubble anchor pointing to the button who triggered the method.
The problem is that I am using a UISegmentedControl...
How do I get the id of the button that was tapped on a UISegmentedControl, so I can determine its position and generate the anchor?
thanks for any help.
Look at SegmentViewController.{h,m} in the UICatalog sample project.
The sample code sets up the view using code.
This line
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
is where the magic happens.
- (void)segmentAction:(id)sender
{
//NSLog(#"segmentAction: selected segment = %d", [sender selectedSegmentIndex]);
}
You can also do this in Interface Builder
Assuming that you have (IBAction)segmentAction:(id)sender declared in your ViewController and that the Files Owner is your ViewController, right-click on the UISegmentedControl and make the connection between the UIControlEventValueChanged event to the Files Owner segmentAction
UISegmentedControl acts like a "single" button. It is a single object placed in a single frame unlike the toolbar items which are an array of objects placed in their own frames. A typical usage pattern is to dispatch a message inside a switch statement in your segmentAction method.
I see two options.
Option A: Implement a custom view that contains an array of UIButton controls. The action for the UITouchUpInside event for the all of the buttons can point to the same method in your controller. Then implement a buttonPressed:(id)sender which you can ask the sender for it's frame and location to use to create your new view on top. --> Complicated
Option B: You can calculate the position of the new subview using an offset calculated from selectedSegmentedIndex, widthForSegmentAtIndex:, and contentOffsetForSegmentAtIndex:. Really not much different than calculating from the bounds of any view. --> Easier

Initialize UIPickerView

I want to create a UIPickerView with the easiest way possible, because all of what I know Is not enough to help me
Ok what I ment is that I am trying to get a UISegmented that will end up creating a UIPickerView but I want to create a UIPickerView that shows up when I select one of the segments in the segmented control animated, and also the pickerview is supposed to use an array that has colors like red green blue
Ok what I ment is that I am trying to get a UISegmented that will end up creating a UIPickerView but I want to create a UIPickerView that shows up when I select one of the segments in the segmented control animated, and also the pickerview is supposed to use an array that has colors like red green blue
For your UISegmentedControl, you'll need to register target-action methods. For example:
[segmentedControl addTarget:self
action:#selector(updatePicker:)
forControlEvents:UIControlEventValueChanged];
Inside of updatePicker, set a variable that corresponds to whatever you want to show in your picker. Then, to your picker instance (you should only have one instance of this class), send the reloadAllComponents message. This will update the picker by querying the delegate for new data. In your delegate (which can probably all be the same class), you'll want to check the value of the variable you set in updatePicker to determine what data to return to the picker.
This page has video and instructions on how to add UIPickerView programmatically in Swift, i.e. it does not use Interface Builder or Story Board, everything is done in a few lines of code.
http://www.appswiftprogramming.com/pg/2171/UIPickerView_Programmatically
You can add your custom view in the UIPickerView if you want something more advanced. It shows that too.

UITextField and UITableViews... Am I doing this correctly? If not, what is the best way?

I have an array of folders. Each folder is listed as a table view row.
When I display my table, I populate it with a set of textfields on the left hand side of the row (i want the user to be able to edit them) and a set of switches (on/off) on the right hand side of the row.
All is working well, you can touch the textfield and the keyboard appears. You can changed the values of the switch each time also.
The problem I'm having is knowing which text field has been changed so that I can update my array ready to save the values.
I'm using..
[textField addTarget:self action:#selector(textFieldDone:) forControlEvents:UIControlEventEditingDidEndOnExit];
and...
-(void)textFieldDone:(UITextField *)textField
The problem is that the textField object does not contain any unique information about it in the textFieldDone selector. I've tried setting
[textField setTag:rowNumber];
But it doesn't show as tag is not part of the textField object.
Anyone any ideas on the best way of doing this? Surely there must be lots of applications that have have textfields in table rows that you can switch between?
Or maybe I'm missing something here....
Actually 'tag' is part of the UITextField as it is inherited from UIView.
Maybe I can suggest a different approach. Use your table view to display the data with a checkmark in the accessory view if the boolean value you are representing with a switch currently is set to YES. When the user taps that row, push a new view controller that contains a text field and a switch that the user can edit.
Is there an application you've seen that uses the UI method your attempting with the text field and switch in a table cell?
Keep in mind that you are probably reusing table cells, which is what you're supposed to do, however you may not be setting the tag on subsequent uses of that cell. Just guessing here.