i am trying to implement an action sheet that contains a picker view and a segmented control bar with a previous button, next button and done button like the image as follows http://imgur.com/8wVMy. I currently am able to make it look like this http://imgur.com/AXn6H. I was wondering if someone could help me get the picker view to sit on the bottom and just make it look a little better. Thanks for any help.
Unless you're targeting very old versions of iOS (i.e. versions earlier than 3.2), the best way to do it is to take a completely different approach.
As of 3.2, any UIResponder (which includes all UIViews) can return a UIView from its inputView property to show that view instead of the keyboard when the view becomes the first responder. This even works for views that normally don't become first responder or don't display the keyboard at all. It's simple:
Design your popup view, as you would any other view.
Ensure that your widget view returns YES from canBecomeFirstResponder.
Ensure that your widget view returns an instance of your popup view from inputView.
More details are available in the documentation.
Also, BTW, if you're on an iPad you should probably use a UIPopoverController to display a UIPickerView instead of either of these methods. Apple may actually require this if you intend to get your app in the app store.
The next and previous buttons are actually showing your images to segmentedController Within a toolbar. To get it You have to define the segmentedController and UIToolbar on. H. Next add the DataSource and UIPickerView
Then in the viewDidLoad create objects and define Their properties. For example:
if (keyboardToolbar == nil) {
keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
[keyboardToolbar setBarStyle:UIBarStyleBlackTranslucent];
segControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Anterior", #"Siguiente", nil]];
[segControl setSegmentedControlStyle:UISegmentedControlStyleBar];
[segControl setTintColor:[UIColor blackColor]];
segControl.frame = CGRectMake(5, 7, 150, 33);
segControl.momentary = YES;
[segControl addTarget:self action:#selector(segSelected:) forControlEvents:UIControlEventValueChanged];
UIBarButtonItem *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *aceptar = [[UIBarButtonItem alloc] initWithTitle:#"Hecho" style:UIBarButtonItemStyleDone target:self action:#selector(cerrarTeclado:)];
//aceptar.width = 70.0f;
[keyboardToolbar setItems:[[NSArray alloc] initWithObjects: extraSpace, aceptar, nil]];
[keyboardToolbar addSubview:segControl];
}
Related
I have a backbarButtonItem in ViewController2 and when the screen goes back to its parent viewcontroller, ViewController1, I want to ask the user if he is ready to go back. If he's not ready, I want to give him an option to stay in ViewController. So ask something like - "Are you ready to leave this screen? - YES or NO"
I know that backbarButtonItem cannot call 'action' as defined in Apple doc. Do you have any good solution?
I would add your own custom leftBarButtonItem to the navigation item, and add whatever action method you want to it. It won't have the same look as the standard back button, but I think that's a good thing -- users expect that the standard button will have a standard behavior. Using a regular rectangular button will alert the users that something different is going on.
Write this in in view didLoad method:
UIImage* myimage = [UIImage imageNamed:#"ButtonImage.png"];
CGRect backFrame = CGRectMake(0, 0, 80, 30);
backButton = [[UIButton alloc] initWithFrame:backFrame];
[backButton setBackgroundImage:myimage forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(MyBtnclicked)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *btn = [[UIBarButtonItem alloc]initWithCustomView:backButton];
self.navigationItem.leftBarButtonItem = btn;
and then write ibaction as follows
-(IBAction)MyBtnclicked
{
UIAlertView *av=[[UIAlertView alloc] initWithTitle:nil message:#"Do you really want to Go back" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes",nil];
[av show];
}
One approach would be to subclass the UINavigationController object and override the popViewController:animated: method. You can then decide, based on the user's response, whether to call super's popViewController:animated: or not.
I've subclassed UIPickerView to add some a little more functionality(I'm 99% sure it has nothing to do with this question). In drawRect I added a toolbar to make dismissing the toolbar a little easier, the problem is, neither the UIToolbar, or the UIBarButtonItem inside the toolbar receive touches. It's almost as if the view is "invisible" in that the touches are forwarded to the view behind it(a UITableView). I know I could just make a "control" view that holds both the picker an a toolbar. But I just wanted to know if there was any way to do this without creating another view?
Here's my drawRect code:
- (void)drawRect:(CGRect)rect
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
pickerToolbar = [[UIToolbar alloc] initWithFrame: CGRectMake(0, 0, self.frame.size.width, 40)];
UIBarButtonItem *closeButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemDone target: self.delegate action: closeAction];
[pickerToolbar setItems: [NSArray arrayWithObject: closeButton]];
[self addSubview: pickerToolbar];
}
}
Here's a photo:
Never, never do this. You are adding a new subview every time the picker is drawn!
If your picker view is the input view of a text field, simply create a toolbar and add it as the input accessory view. It will then appear above the picker for you. This is the standard way to achieve this behaviour.
I have implemented a UISegmentControl as the rightBarButton of my detailViewController.
This view controller displays that of the information passed through from a UITableView.
This UITableView's cells are populated with CoreData attribute values.
What I want to do is enable the user to go up and down in the list via the detailViewController. Instead of having to make the user have to go back to the rootViewController, they'll gain the ability to scroll through via the UISegmentControl.
I currently have this in my detailViewController.m
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Setting up UISegmentedControl
// Segmented Control - Custom right bar button with a view
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:
[NSArray arrayWithObjects:
[UIImage imageNamed:#"arrowdown.png"],
[UIImage imageNamed:#"arrowup.png"],
nil]];
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.frame = CGRectMake(0, 0, 75, 30);
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.momentary = YES;
UIBarButtonItem *segmentBarItem = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
[segmentedControl release];
self.navigationItem.rightBarButtonItem = segmentBarItem;
[segmentBarItem release];
}
This is then attached to the following method, for detecting the tapped control.
- (void)segmentAction:(id)sender
{
UISegmentedControl* segCtl = sender;
// the segmented control was clicked, handle it here
if([segCtl selectedSegmentIndex]==0){
NSLog(#"You clicked the down arrow - the segment clicked was %d", [segCtl selectedSegmentIndex]);
}else {
NSLog(#"You clicked the up arrow - the segment clicked was %d", [segCtl selectedSegmentIndex]);
}
}
I am also curious as to whether or not anyone knows how to detect whether or not there is anymore to go to. So say, if the note loaded is in the first position, then the down arrow is disabled, and if the note loaded is in the last position, the up arrow is disabled. Is this even possible?
Any help would be greatly appreciated.
I'd suggest you to create a formal protocol MyDataSource which provides methods for accessing the data. As a minimum, there must be a method to get number of data objects and object for a specified index.
In your DetailViewController you should have a reference to an object which conforms to MyDataSource. I'd recommend you to use instance of RootViewController as a data source for DetailViewController.
You should also keep track of index of the object that is currently displayed in DetailViewController and update UI appropriately.
I am looking to create a bar with a couple of buttons at the top of the iPhone interface just under the statusBar, the controller is a simple UIViewController so this is a bar for buttons not for navigation. I have got things working but it feels a little clunky and I was wondering if I was doing it right and not missing any shortcuts.
There is no action / selector: set yet as I am just setting this up.
I will probably remove the NSArray convenience method and add an alloc/release.
Code:
- (void)loadView {
// VIEW
UIView *tempView = [[UIView alloc] initWithFrame:screenFrame];
// NAV BAR
UINavigationBar *tempNavigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[tempNavigationBar setBarStyle:UIBarStyleBlack];
UIBarButtonItem *testButton = [[UIBarButtonItem alloc] initWithTitle:#"TEST" style:UIBarButtonItemStyleBordered target:self action:nil];
UINavigationItem *navItem = [[UINavigationItem alloc] init];
[navItem setLeftBarButtonItem:testButton];
[testButton release];
[tempNavigationBar setItems:[NSArray arrayWithObject:navItem]];
[tempView addSubview:tempNavigationBar];
[tempNavigationBar release];
[navItem release];
[self setView:tempView];
[tempView release];
}
That looks alright to me. An alternative would be to do this in Interface Builder, but that's a completely different matter.
If you intend to support autorotation, you may have to add some more code to set autoresize masks for your navigation bar so it expands correctly. Actually, I would use Interface Builder for this, because I'm big on visualizing my autoresize masks.
Yeah the question repeats but why you don't preferred I.B.? As you don't need navigational functionality then you need to look into an alternate i.e. UIToolBar comes to mind. its usage is same as navigation bar as you need to setItems with NSArray as you are doing.
I hope you will succeed in finding your proper solution.
On both the iPhone and the iPad I have a need to present two buttons on the right hand side of a navigation bar. I'm doing this with the following snippet of code:
UIToolbar *rightBarButtons = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 92, 44.01)];
UIBarButtonItem *send = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction
target:self
action:#selector(send)];
[send setStyle:UIBarButtonItemStyleBordered];
UIBarButtonItem *add = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(addRecipe:)];
[add setStyle:UIBarButtonItemStyleBordered];
NSArray *buttons = [[NSArray alloc] initWithObjects:send,add,nil];
[send release];
[add release];
[rightBarButtons setItems:buttons];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:rightBarButtons];
[buttons release];
[rightBarButtons release];
On the iPhone the colours are fine, and in landscape mode on the iPad it is fine as they are grey. However in portrait mode the view appears inside a popover controller which has a dark black/blue colour. My buttons and the toolbar show up as the default grey.
How can I make the toolbar buttons match? If you do not use the hack above and just present one button as normal the colour change is handled and I guess I just need to implement that colour change manually, problem is, I can't seem to get the colour to change at all.
This would appear to be a property called barStyle and not tintColor as I previously thought. The simplest solution is to copy the bar style from elsewhere:
[rightBarButtons setBarStyle:self.navigationController.navigationBar.barStyle];
It's then fairly trivial to ensure the style remains correct as the view changes. Although I have to say I quite liked the dark blue black buttons over the silver navigation bar that gave after rotation.