UIPickerController - want to show specific selection upon loading - xcode

I have a custom UIPickerView that is embedded into an UIActionsheet that comes up half the screen when called. Works great. The problem is that I want to have the barrelPicker be showing the 'most probable' results as the selection when it first comes up (after all the data has been loaded into it).
Prior to having the custom picker embedded in the action sheet, I had it in a UIViewController and was just calling "showProbableResults" (a custom method of mine) in the viewDidLoad method of the ViewController, because I knew at that point, the UIPickerView would be loaded up and ready to go. Is there an equivalent place for me to call this method now or do I need to rethink my whole design? Essentially, what I need is a place to call this after the UIPickerView has been loaded.
- (void)startWithDelegate:(UIViewController <ImageProcessingDelegate> *)sender
{
self.delegate = sender;
self.showFirstBottle = YES;
[self start];
}
- (void) start {
self.actionSheet = [[UIActionSheet alloc] initWithTitle:#"Choose Something"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
[self.actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
NSLog(#"1.) About to alloc the picker");
self.vintagePicker = [[UIPickerView alloc] initWithFrame:pickerFrame];
self.vintagePicker.showsSelectionIndicator = YES;
self.vintagePicker.dataSource = self;
self.vintagePicker.delegate = self;
[self.actionSheet addSubview:self.vintagePicker];
[self.vintagePicker release];
UISegmentedControl *nextButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Next"]];
nextButton.momentary = YES;
nextButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
nextButton.segmentedControlStyle = UISegmentedControlStyleBar;
nextButton.tintColor = [UIColor blackColor];
[nextButton addTarget:self action:#selector(show:) forControlEvents:UIControlEventValueChanged];
[self.actionSheet addSubview:nextButton];
[nextButton release];
UISegmentedControl *backButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:#"Back"]];
backButton.momentary = YES;
backButton.frame = CGRectMake(10, 7.0f, 50.0f, 30.0f);
backButton.segmentedControlStyle = UISegmentedControlStyleBar;
backButton.tintColor = [UIColor blackColor];
[backButton addTarget:self action:#selector(cancel:) forControlEvents:UIControlEventValueChanged];
[self.actionSheet addSubview:backButton];
[backButton release];
[self.actionSheet showInView:_delegate.parentViewController.tabBarController.view]; // show from our table view (pops up in the middle of the table)
[self.actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
}

One option is to create a reusable picker view, as shown here, and then call the #optional
-(void)setInitialPickerValueToRow:(int)i inComponent:(int)j animated:(BOOL)k{
[pickerView selectRow:i inComponent:j animated:k];
}
from any view controller or NSObject (such as your UIActionSheetDelegate).
Your other option is to set a standard pre-chosen selection, as follows:
self.vintagePicker = [[UIPickerView alloc] initWithFrame:pickerFrame];
self.vintagePicker.showsSelectionIndicator = YES;
self.vintagePicker.dataSource = self;
self.vintagePicker.delegate = self;
[self.actionSheet addSubview:self.vintagePicker];
[self.vintagePicker selectRow:0 inComponent:0 animated:NO];
You could also have different variables that you set, and have selectRow:inComponent:animated: access those, instead of being preset.
[self.vintagePicker selectRow:myRow inComponent:0 animated:NO];
Hope this helps!

Related

Activity Indicator will not go away

I am using the following code to show an Activity Indicator while some data is loading. The problem is that when I try to hide it again. The Activity Indicator stays put. The screen lightens a bit but that is it.
To show it:
self.overlayView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.overlayView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.3];
self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
self.activityIndicator.center = self.overlayView.center;
[self.overlayView addSubview:self.activityIndicator];
[self.activityIndicator startAnimating];
[self.tableView addSubview:self.overlayView];
To hide it:
[self.activityIndicator stopAnimating];
[self.overlayView removeFromSuperview];
Try to add your overlayView to the superview of your tableView :
[self.view.superview addSubview:self.overlayView];
I figured it out with a combination of stackoverflow questions. Here is my code to show the UIActivityIndicatorView
-(void)loadView {
[super loadView];
self.overlayView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.overlayView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.3];
self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
self.activityIndicator.center = self.overlayView.center;
[self.overlayView addSubview:self.activityIndicator];
[self.tableView addSubview:self.overlayView];
[self.activityIndicator startAnimating];
}
Here is the code to hide it. It looks like putting the code in the loadView event made all the difference.
[overlayView removeFromSuperview];

Getting multiple table view instances to match

I'm trying to get the cells returned within my searchResultsTableView to look just like those in the "regular", non-search table view. Here's my regular view.
The first time you search, the results are styled exactly like the "regular" table view. However, once you you cancel the searchDisplayController and tap the Search button again, you'll get this.
It looks to me like the background isn't being set after the first time the search display controller is loaded.
I'm instantiating cells in tableView:cellForRowAtIndexPath: using UITableViewCell, not a custom subclass. Here is the remainder of the method:
PersonInfo *info = nil;
if (tableView == self.searchDisplayController.searchResultsTableView) {
info = [self.filteredPeopleList objectAtIndex:indexPath.row];
} else {
info = [self.peopleList objectAtIndex:indexPath.row];
}
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cellBk.png"]];
cell.detailTextLabel.textColor = [UIColor whiteColor];
cell.backgroundColor = [UIColor clearColor];
cell.imageView.image = info.image;
cell.textLabel.text = info.name;
cell.detailTextLabel.text = info.title;
return cell;
The tableView (the "regular" one) and searchResultsTableView is being set as follows inside viewDidLoad:
//Set the default tableView style
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.opaque = NO;
self.tableView.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background.png"]];
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
//Set the self.searchDisplayController background stuff
self.searchDisplayController.searchResultsTableView.backgroundColor = [UIColor clearColor];
self.searchDisplayController.searchResultsTableView.opaque = NO;
self.searchDisplayController.searchResultsTableView.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"background.png"]];
[self.searchDisplayController.searchResultsTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
[self.tableView reloadData];
Moving the code to style the searchResultsTableView into searchDisplayController:willShowSearchResultsTableView:, a method of UISearchDisplayDelegate, takes care of this.

How can we put two line in UIBarButtonItem in Navigation Bar

"Now Playing" is in One line in UIBarButtonItem. I have to put it in two lines, like "Now" is ay top and "Playing" is at bottom.I have written the following line of code:-
UIBarButtonItem *flipButton = [[UIBarButtonItem alloc]
initWithTitle:#"Now Playing"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(flipView)];
self.navigationItem.rightBarButtonItem = flipButton;
So i want to pu line break in between "Now Playing". So please help me out.
Yes you can. It is fairly simple to do. Create a multiline button and use that. The "trick" is to set the titleLabel numberOfLines property so that it likes multilines.
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
button.titleLabel.numberOfLines = 0;
[button setTitle:NSLocalizedString(#"Now\nPlaying", nil) forState:UIControlStateNormal];
[button sizeToFit];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
When you specify a button type of custom it expects you to configure everything... selected state, etc. which is not shown here to keep the answer focused to the problem at hand.
- (void)createCustomRightBarButton_
{
UILabel * addCustomLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 64, 25)] autorelease];
addCustomLabel.text =#"Now\nPlaying";
addCustomLabel.textColor = [UIColor whiteColor];
addCustomLabel.font = [UIFont boldSystemFontOfSize:11];
addCustomLabel.numberOfLines = 2;
addCustomLabel.backgroundColor = [UIColor clearColor];
addCustomLabel.textAlignment = UITextAlignmentCenter;
CGSize size = addCustomLabel.bounds.size;
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
[addCustomLabel.layer renderInContext: context];
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage * img = [UIImage imageWithCGImage: imageRef];
CGImageRelease(imageRef);
CGContextRelease(context);
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithImage:img
style:UIBarButtonItemStyleBordered
target:self
action:#selector(flipView)]
autorelease];
}
You can host a UIButton as customView inside your bar button (either set the bar button item customView or you can drag one directly on top of your UIBarButtonItem), hook it up as an outlet, then do;
-(void) viewDidLoad
{
//...
self.customButton.titleLabel.numberOfLines = 2;
self.customButton.suggestionsButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
self.customButton.suggestionsButton.titleLabel.textAlignment = UITextAlignmentCenter;
}
which in my case becomes
I create 2 PNG images by myself, and it looks good.
UIImage *img = [UIImage imageNamed:#"nowplaying.png"];
UIBarButtonItem *nowPlayingButtonItem = [[[UIBarButtonItem alloc] initWithImage:img style:UIBarButtonItemStyleBordered target:delegate action:#selector(presentNowPlayingMovie)] autorelease];

InputAccessoryView of a UITextField

I need to stick a toolBar with a UITextField inside to a keyboard.
What if I make the whole toolBar (which I think is the textField's super view) the inputAccessoryView of its textField?
I mean like this:
textField.inputAccessoryView = toolBar; // textField is inside the toolBar
I've been trying on this but I have not made it work yet.
Anyone can help?
Or is there another way to achieve what I want?
- (void)viewDidLoad
{
[self createAccessoryView];
[textField setDelegate:self];
[textField setKeyboardType:UIKeyboardTypeDefault];
[textField setInputAccessoryView:fieldAccessoryView];
}
- (void)createAccessoryView
{
CGRect frame = CGRectMake(0.0, self.view.bounds.size.height, self.view.bounds.size.width, 44.0);
fieldAccessoryView = [[UIToolbar alloc] initWithFrame:frame];
fieldAccessoryView.barStyle = UIBarStyleBlackOpaque;
fieldAccessoryView.tag = 200;
[fieldAccessoryView setBarStyle:UIBarStyleBlack];
UIBarButtonItem *spaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(done:)];
UISegmentedControl* segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:NSLocalizedString(#"Previous", #""), NSLocalizedString(#"Next", #""), nil]];
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
[segmentedControl setMomentary:YES];
UIBarButtonItem *segmentButton = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
[fieldAccessoryView setItems:[NSArray arrayWithObjects:segmentButton, spaceButton, doneButton, nil] animated:NO];
[segmentButton release];
[spaceButton release];
[doneButton release];
[segmentedControl release];
}
When are you setting the property? You may be setting it after the view has already loaded.
Try setting it in
- (void) viewDidLoad

How to modal the view when network connecting

Is there any way to set the view page modal during network connecting? I mean all controllers in page do not response the user operation if the network is connecting?
I updated code like:
- (void)loadView
{
[super loadView];
_hudView = [[UIView alloc] initWithFrame:CGRectMake(75, 155, 170, 170)];
_hudView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
_hudView.clipsToBounds = YES;
_hudView.layer.cornerRadius = 10.0;
_activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
_activityIndicatorView.frame = CGRectMake(65, 40, _activityIndicatorView.bounds.size.width, _activityIndicatorView.bounds.size.height);
[_hudView addSubview:_activityIndicatorView];
[_activityIndicatorView startAnimating];
_captionLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 115, 130, 22)];
_captionLabel.backgroundColor = [UIColor clearColor];
_captionLabel.textColor = [UIColor whiteColor];
_captionLabel.adjustsFontSizeToFitWidth = YES;
_captionLabel.textAlignment = UITextAlignmentCenter;
_captionLabel.text = #"Loading...";
[_hudView addSubview:_captionLabel];
NSArray *buttonNames = [NSArray arrayWithObjects:#"hehe",#"xixi",nil];
UISegmentedControl *segmentControl = [[UISegmentedControl alloc] initWithItems:buttonNames];
segmentControl.frame = CGRectMake(0, 0, TTApplicationFrame().size.width/2, TT_ROW_HEIGHT-10);
segmentControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentControl.momentary = NO;
segmentControl.tintColor = [UIColor darkGrayColor];
segmentControl.selectedSegmentIndex = 0;
[segmentControl addTarget:self action:#selector(switchPage:) forControlEvents:UIControlEventValueChanged];
self.navigationItem.titleView = segmentControl;
TT_RELEASE_SAFELY(segmentControl);
self.view = [[[UIView alloc] initWithFrame:TTApplicationFrame()] autorelease];
self.tableView = [[[UITableView alloc] initWithFrame:TTApplicationFrame() style:UITableViewStylePlain] autorelease];
self.tableView.rowHeight = 80.f;
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:self.tableView];
[self reload];
[self updateView];
}
and show it like:
- (void)showLoading:(BOOL)show {
if (show) {
self.loadingView = _hudView;
}
else {
self.loadingView = nil;
}
}
As I said in comment, it still cannot cover the buttons of UISegmentedControl, user still can click those buttons...
Instead of using a modalViewController, create a HUD (one of the nice views with a UIActivityIndicators you'll see in the TTCatalogue app) that will block the view and inform the user something is happening while you're making a request.
Just insert them by a [self.view addSubview:theHUDview];.
It's not necessarily good design though, instead, make your network calls asynchronously, in the background.

Resources