iphone UIPickerView question - iphone

Here's the situation, I'm a newb at this - so I could be totally on the wrong path.
I am building an app with multiple views; in one of those views I need the user to select from a dropdown list (UIPickerView) --> for simplicity let's call that view "PC" which has PC.h and PC.m files.
Through IB I was able to drop a UIPickerView object to the PC view, and I initialize that "object" in my ViewController.h and ViewController.m files. Meaning, I'm able to load the view, populate data in the view, etc. etc.
My challenge/problem is - I want the UIPicker to be hidden until the user clicks a button on the PC view, then I want to show the UIPicker and hide it again once the user selects something from the menu.
I've searched and searched and can't find anything, so any help here is appreciated!

assuming that your UIPickerView instance (object) is called pv;
This is how your header-file may look like:
#interface YourViewController : UIViewController
{
IBOutlet UIPickerView *pv;
}
#property (nonatomic, retain) UIPickerView *pv;
#end
You then need to connect the pv-instance within the InterfaceBuilder to your Picker-View.
Trivial Approach:
somewhere in your viewDidLoad of the embedding view-controller:
pv.hidden = YES;
within the button action method (connected to your button-touch-up-instide event):
pv.hidden = NO;
within the action method of your "menu"
pv.hidden = YES;

Related

Cant load UITableView

Ok, this is really really easy, but even though I went through 100s of tutorials, I still have no idea whats wrong with my app. All I want to do is just to display a table view, even empty, but I get a black screen on the simulator and an exception in the output too.
This is what I did (followed step by step a few tutorials):
Open a view based app
This is my header:
#interface TableViewsViewController : UIViewController <UITableViewDelegate> {
IBOutlet UITableView *tblSimpleTable;
}
#property (nonatomic, retain) IBOutlet UITableView *tblSimpleTable;
#end
did not do anything in .m besides synthesizing.
IB: made 3 connections: delegate, dataSource, and tblSimpleTable to File's owner.
Yes, I am a beginner, but this is ridiculous...appreciate any help. Thanks!
First off, a table view has two "delegate" types -- the table view delegate and the table view data source. Your interface is being a delegate, but not a data source, for the table view.
If you add UITableViewDataSource to the interface, i.e.
#interface TableViewsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
and then compile, you'll probably get errors about missing methods for number of sections and for cell. After you add these to your implementation, the table view should work.
My guess is the table view tries to ask your class for number of sections in the table, and since your class doesn't actually respond to that selector, the code crashes.
Add
tblSimpleTable.delegate = self
in viewDidLoad
...and ensure you have connected it correctly in interface builder.

Objective-C Novice. Change property in Controller from another Controller?

The context: I have three views. One Introductory view, an Upload view and the Main view. As classes (With their respective headers) I have the rootViewController (SwitchViewController), IntroViewController and UploadViewController. The first view to be shown is IntroView. The user presses a button (declared in SwitchViewController) that takes them to the UploadView, then in the UploadView they get to choose an image and press the button again to go back to IntroView.
The thing is that while the user gets to pick the image with UIImagePickerController the button to switch views won't hide nor a UIImageView I have with a logo on top of the view(screen). The UIImageView and the UIButton are both declared in SwitchViewController's header.
The code used:
UploadViewController.h
#import [...] //Imports
#class SwitchViewController;
#interface UploadViewController :
UIViewController <UIImagePickerControllerDelegate,
UINavigationControllerDelegate,UIActionSheetDelegate> {
UITextField *imageTextField;
UIImageView *uploadedImage;
SwitchViewController *switchViewController;
[...]
}
#property (nonatomic, retain) SwitchViewController *switchViewController;
#property (nonatomic, retain) IBOutlet UITextField *imageTextField;
#property (nonatomic, retain) IBOutlet UIImageView *uploadedImage;
[...]
#end
UploadViewController.m
[...]
- (IBAction) selectImageButtonPressed {
self.switchViewController.submitButton.hidden = YES;
self.switchViewController.imageLogo.hidden = YES;
[...] //continues
I just begun recently programming in objective-c so please forgive me if the question is very essential. I have looked and am following "Beginning iPhone 3 Development" of APRESS. But even if it helps to greatly understand the basics sometimes I get lost.
PS: If it is clearer to answer the question the SwitchViewController.h and .m snippet codes can be provided if asked. But I thought this text is big as it is.
#Joze i think I may have understood your problem switchViewController is a variable of the class UploadViewController so if you do anything with that variable it wont affect the switchViewController view. so when you are calling the switchViewController view at that time you have to do initWithNibName: bundle: and then hide the button and imageView and also you need to do something like switchViewController.delegate = self; and then call the view modally or what ever way you want it.
PS. i m not sure the that spelling is correct. i dont have xcode at my home.
I hope your problem solves with this.
I solved my problem after refactoring the whole code and changing the general structure of the program itself. Now I have 3 views and each with a viewController to control it. All the switching of views occurs in the Delegate since he has access to everyone. That way I can control every property with every controller, without much difficulty. Changing the property of one of the objects present in one view from another view is difficult and rather inconvenient if not sometimes impossible.
The approach I took when asking this question was short sighted for the application that had to be done. I thank all those who tried to help.

iPad UISplitViewController multiple root views

I am developing for iPad and have created a standard UISplitViewController application using the template provided in Xcode - a standard UITableView on the left and a detail view on the right.
I have modified the template so that when a user selects a table cell from the left view it pushes a new table view in it's place (still on the left side). This works without issue, but I would like to be able to update the existing detail view from the new table view - kinda like how Apple's Mail application works.
- I am not trying to create multiple views on the detail view (right hand side) - I've read the documentation and seen the sample code provided by Apple.
I read/followed many tutorials, but can't seem to get this relatively simple view hierarchy to work.
More detail:-
Using detailViewController.detailItem = #"Test"; in the RootView didSelectTableRowAtIndexPath delegate method updates the Detail view label. Using the exact same code in the newly pushed Table View does not update the label - am I missing a reference point or something??
Since posting I've tried to use protocols & delegates to update a label on the detail view. The label updates correctly when changed from the Root View using the new methods, however, when I push a new view onto the root view (left hand side) I can no longer update the label.
At some point after creating the RootViewController (or maybe even in a custom init method) you are setting the delegate for the DetailViewController, its a common mistake that when a new rootViewController is pushed onto the NavController that you forget to set the delgate again.
You probably are creating a new controller in the:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
method and recording/incrementing the level of the new controller before you push it onto the navController. After you create this new controller, set the delegate again.
newRootController.myDelegate = self.myDelegate;
Before you do this If you NSLog the delegate just before you use it, you will probably find its nil.
Try the viewControllers property of your UISplitViewController
#property(nonatomic, copy) NSArray
*viewControllers Discussion The array in this property must contain exactly
two view controllers. The view
controllers are presented
left-to-right in the split view
interface when it is in a landscape
orientation. Thus, the view controller
at index 0 is displayed on the left
side and the view controller at index
1 is displayed on the right side of
the interface.
The first view controller in this
array is typically hidden when the
device is in a portrait orientation.
Assign a delegate object to the
receiver if you want to coordinate the
display of this view controller using
a popover.
Please beware of the detailViewController! You have to pass this instance variable to your new root view. So something like this:
newRootViewController.detailViewController = self.detailViewController
Otherwise your new root view will never know about the detailView. For your new root(table)view you have to do things like:
#import <UIKit/UIKit.h>
#class DetailViewController;
#interface VorhersageTable : UIViewController {
UITableView *vorhersageTableView;
DetailViewController *detailViewController;
}
#property (nonatomic, retain) IBOutlet UITableView *vorhersageTableView;
#property (nonatomic, retain) DetailViewController *detailViewController;
#end
to declare the property of the detailViewController in your new class.
Add this in your RootViewController.didselectRow, before you push the second table (e.g SubRoot)
SubRoot *subController = [[SubRoot alloc] initWithNibName:#"SubRoot" bundle:nil];
subController.detailViewController = self.detailViewController;
And create the SubRoot.h and SubRoot.m similar to RootViewController.
#class DetailViewController;
#interface SubRoot : UITableViewController {
DetailViewController *detailViewController;
}
#property (nonatomic, retain) DetailViewController *detailViewController;
#end
then synthesize detailViewController.
Hope it helps.

iPhone: Proper use of View and View Controller

I've recently been doing a lot of Objective-C programming, and just got back into doing more iPhone development. I've done a lot of programming using MVC in other languages/frameworks, but I just want to make sure I'm using MVC properly in my iPhone Development.
I created a new iPhone Utility Application, which creates two views: MainView and FlipsideView. Both have a controller (FlipsideViewController and MainViewController) and XIB file of their own.
What I've been doing is putting the IBOutlet UIControl myControl variables in my MainView.h or FlipsideView.h files and then tying the controls in Interface Builder to those variables. Then I put any IBAction SomeAction myAction methods in the MainViewController.h and FlipsideViewController.h files and tying the events to those methods in Interface Builder.
This seems to be conceptually correct, but seems to cause problems. Say I have a button that when clicked it changes a label's text. So the Controller doesn't have a clue of what the variable name of the label is in the OnTouchUp event handler for my button. So I make a #property for it. But since the MainViewController.view property isn't of type MyView, I get warnings or errors whenever I try to access those properties from the view controller.
I am doing this correctly? Is there a better way to do this? If this is correct, how do I properly work with those variables without getting warnings or errors?
Thanks
Here's some code showing what I'm doing:
MainView.h
#import ...
#interface MainView : UIView
{
IBOutlet UILabel* label;
IBOutlet UIButton* button;
}
#property UILabel* label;
#property UIButton* button;
#end
MainViewController.m
-(void) buttonTouchUp:(id) sender
{
self.view.label.text = #"The button was pressed!"; //This gives error because label is not in the view structure or union
[self.view label].text = #"The button was pressed!"; //This gives a warning
}
I know I can cast the view to be of the right type, but that seems like a hack job.
I know I can live with the warning, but a warning says to me that I'm doing something that I probably shouldn't be doing. I don't believe the SDK would set me up to do have to do something like that all the time.
I must just be misunderstanding what the View is supposed to be and I'm using it incorrectly.
Most code I've seen and written myself keeps all the outlets and the actions on the controller. The button sends a message to the controller (via IBAction), then the controller updates the label (via IBOutlet). In other words, putting outlets on your views is unusual.
Views shouldn't be connected to other views unless they have some special relationship, like maybe back/forward buttons that target a UIWebView... but even then, you find out you need a controller to enable/disable the buttons as appropriate.

iPhone Views at Runtime?

I am new to the iPhone SDK and am trying to create 3 views and switch between them. Data will come from a server and I will basically be showing 1 view and caching the other two. So far I am just trying to create a view and display it at run-time. My code is listed below. It shows only a blank screen and I think I am missing a key concept. Any Help?
#import <UIKit/UIKit.h>
#import "ImageViewController.h"
#interface Test5ViewController : UIViewController
{
IBOutlet UIView *rootView;
ImageViewController *curImage;
ImageViewController *nextImage;
ImageViewController *prevImage;
}
#property(nonatomic,retain) IBOutlet UIView *rootView;
#property(nonatomic,retain) ImageViewController *curImage;
#property(nonatomic,retain) ImageViewController *nextImage;
#property(nonatomic,retain) ImageViewController *prevImage;
#end
and
- (void)loadView
{
self.curImage = [[ImageViewController alloc]initWithNibName:#"ImageView" bundle:[NSBundle mainBundle]];
UIImage *pic = [UIImage imageNamed:#"baby-gorilla.jpg"];
[self.curImage assignImage:pic];
self.rootView = self.curImage.view;
}
and
#import <UIKit/UIKit.h>
#interface ImageViewController : UIViewController
{
IBOutlet UIImageView *image;
}
-(void)assignImage:(UIImage *)screenShotToSet;
#property(nonatomic,retain) IBOutlet UIImageView *image;
#end
Welcome to the iPhone SDK!
In general, there are two ways to get any view displayed.
First, and most commonly, you use a NIB file created by the Interface Builder. This is usually the easiest way to get started and I would recommend it for what you're trying to do here. It's too lengthy to describe all the steps you need to do for what you have here, but basically start in xcode by creating a new file and selecting "user interfaces" and choose View XIB. This will create a basic NIB file (they're called NIBs rather than XIBs for historical reasons). The first step in interface builder is to change the class name of the "File's Owner" to your UIViewController subclass (Test5ViewController). You can then drop anything that IB will allow into the view window or even replace the pre-supplied view object with one of your own. And here's the trick: make sure the view outlet (supplied by the UIViewController superclass) is connected to a view. Once this is done, this view will be automatically loaded when your NIB is loaded. You can then just put your UIViewController subclass (Test5ViewController) in your MainWindow.xib NIB file to get it automatically loaded, and you're in business.
Now, the way you're doing it here is the second way. Some people like to code this way all the time and not user interface builder. And while it's definitely necessary sometimes and always more flexible, it makes you understand what is happening a bit better. There may be other things, but the main thing you're missing is that in your code above, you have nothing that is adding your view into the view hierarchy. You need to check first that you have an UIApplicationDelegate subclass and it needs to load your "root" UIViewController class. All initial project creation types in xcode do this (except Window-based application). It is code like:
[window addSubview:rootController.view];
Once this is done, if your view controller wasn't loaded by the NIB (described briefly above), your loadView method will be called, expecting you to build your own view hierarchy. Above, you created the view(s), but failed to put them in a hierarchy. You need something like:
[self.view addSubview:curImage.view];
No view will be rendered until added to the view hierarchy. Make sure to look up the UIView class in the documentation and understand the variety of ways to add and remove views to the view hierarchy.
A couple things I should warn you about:
* your code above is leaking. You need to review how objective-C properties work. There's lots on this site about it. More than I have time to write about here.
* don't create a rootView property in the case you have here. There already is one in the superclass (UIViewController). It's just 'view'. Use that for saving your root view.
I hope this helps you get started. It can be bewildering at first, but you'll soon get it going! I recommend building and rewriting and rebuilding a lot of sample code before you do your "real" application. The SDK has many great samples.