I am working on an iPhone app. Initially, I had my pickerview in the same screen so this was just a one page app. After skinning it i realized that i want the pickerview on it's own separate page. So i did that. However, my pickerview originally would update uilabels and other objects on that same page. How can I have my pickerview access those objects from it's new view?
- (IBAction)ShowPickerAction:(id)sender {
if (self.theView == nil) {
theView = [containerView initWithNibName:#"containerView" bundle:nil];
theView.parentView = self;
}
self.theView.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:self.theView animated:YES];
}
That is the method I am using to call my new view. But line 3 of the above code gives me the error "No known class name for selector initWithNibName:bundle". I think that error is related to something that i did wrong in my header file. My new class is called containerView. So i did this in my header:
#interface ViewController : UIViewController {
containerView *theView;
But that gives me the error "Unknown type name containerView" even though i do have a class named containerView!!
Look into uiappdelegate protocol or try passing values to through a static function to the previous page.
Use a delegate to pass information back and forth to the view object that instantiatrd the picker view. You want to keep your code coupling as loose as possible, especially if you might like to drop it into your next project. Using a delegate and/or blocks are some of the best ways.
Related
i don't know if anyone is using this open source library for replacing UIPopovercontroller for an iPhone.
i'm trying to deploy the FPPopover into my project, everything is working like i want, but the problem is that i'm not able to return any value to my ViewController.
i'm trying this in didSelectRowAtIndexPath
myParentViewController *parentController =(myParentViewController*)self.parentViewController;
but the problem is that self.parentViewController is (null)
i have also another problem, how can i dismiss the FPPopoverController from within didSelectRowAtIndexPath.
I dismissed the view by adding a popoverView property to the table view controller that is popping up (in this case ATableViewController), and then assigning the FPPopoverViewController to that property. Like this:
ATableViewController *aTableViewController = [[ATableViewController alloc] init];
FPPopoverController *aPopoverController = [[FPPopoverController alloc] initWithViewController:aTableViewController];
aPopoverController.delegate = aTableViewController;
aTableViewController.popoverView = aPopoverController;
Then in didSelectRowAtIndexPath of aTableViewController you can just call:
[self.popoverView dismissPopoverAnimated:YES];
If you are trying to return values to the "parent"...since the parentViewController property is null here, you can just make your own property for it (let's call it "parentView"). So when setting up the above you would use:
aTableViewController.parentView = self;
Then you can access any of the properties of the parentView and return values from the aTableViewController that popped up. A bit of a workaround, but that's what I did...hope it helps!
I am pretty new with Three20. I have followed ray wenderlich's nice introduction to three20 and the examples within the three20 framework. When I click on a thumbnail in a thumbnail view (subclass of TTThumbsViewController) to launch a Details view, a standard Details image view (deployed by TTPhotoViewController or its super class). I would like to use my own implementation of a Details View instead of the default. I put the following code when I initiated the subclass of TTThumbsViewController and TTThumbsViewControllerDelegate method:
- (id)initWithDelegate:(id<TTThumbsViewControllerDelegate>)delegate {
[super initWithDelegate:delegate];
return self;
}
- (void)thumbsViewController: (TTThumbsViewController*)controller
didSelectPhoto: (id<TTPhoto>)photo {
[navigationController.pushViewController:photoDetailViewController
animated:Yes];
}
But the default TTPhotoViewController view still prevail. When I put a NSLog in the delegate method. I coud see the method was called. I think there is another delegate someone already set in TTThumViewController? Can someone recommend a way to display my detail photo view? Is there another thumbs view controller I can use? Any suggestion will be greatly appreciated.
I'm really new to all of this (coding, etc.) but I'll share what I've found. By looking up the definition of ttthumbsviewcontroller, I was able to find the following method(wrong term?):-
- (void)thumbsTableViewCell:(TTThumbsTableViewCell*)cell didSelectPhoto:(id<TTPhoto>)photo {
[_delegate thumbsViewController:self didSelectPhoto:photo];
BOOL shouldNavigate = YES;
if ([_delegate respondsToSelector:#selector(thumbsViewController:shouldNavigateToPhoto:)]) {
shouldNavigate = [_delegate thumbsViewController:self shouldNavigateToPhoto:photo];
}
if (shouldNavigate) {
NSString* URL = [self URLForPhoto:photo];
if (URL) {
TTOpenURLFromView(URL, self.view);
} else {
TTPhotoViewController* controller = [self createPhotoViewController];
controller.centerPhoto = photo;
[self.navigationController pushViewController:controller animated:YES];
}
}
}
In the else statement, I've found this calls the creation of the photoviewcontroller. By recalling this method (?) in the actual body of my own code and changing the body in the else statement I was able to add a custom detail view. Further down the definition of the ttthumbsnailviewcontroller, you can find that the creatPhotoViewController calls for an initiation of the PhotoViewController so calling that method(?) in the body of the code and initializing another view also works.
If someone can explain whether or not this is a good method of doing this (I have a feeling that is not), it would be appreciated. Also why does putting the method in the body of the code override the call there.
I have 5 different views and when I tap the button, I want to push one of 5 views randomly. However, I do not want to make 5 different controllers for each views. Do I have a chance to put them in one controller? If so, how?
You can have as many views as you want in a single UIViewController subclass. You can create them all in Interface Builder as well, in the one .xib file for your UIViewController class (it might get a bit hard to see, though, better to lay out each UIView in its own .xib). You can present them in any combination you want. Assuming you want to just show one view at a time, you can do this:
In your viewDidLoad method, start out showing the initial view, and in your class keep track of which is the current view:
...
#property(nonatomic, retain) UIView *currentView;
...
- (void)viewDidLoad
{
[self.view addSubview:self.defaultView];
self.currentView = self.defaultView;
}
Then to switch to a particular other view do this:
- (void) switchToView:(UIView *)newView
{
[self.currentView removeFromSuperView];
[self.view addSubview:newView];
self.currentView = newView;
}
}
Or you can show them all at one time: just [self.view addSubview:theView];
You have to set the tags of all the views, and then use
int r = arc4random() % 5;
method to find the random number. Use this newly generated number to check the tag, in your selector
Just change the view outlet of the controller on the action of the button. Use random numbers to select which view. Ouh and - (void)setNeedsDisplay :)
I want to change an image on a view, from a popup dialog of 4-6 icons (imagine like changing your image on a messenger application).
The way I implement this modal popup is by creating a new view at IB, with opacity on the background, and then I load this as a subview:
IconsViewController *iconsViewController = [[IconsViewController alloc] initWithNibName:#"IconsView" bundle:nil];
[self.view addSubview:iconsViewController.view];
So, when the user touches an icon, I have
- (IBAction)iconIsSelected:(id)sender {
switch ([sender tag]) {
case 1:
[(ParentViewController*)[self superview] changeIcon];
break;
case 2:
// same here..
break;
default:
break;
}
[self.view removeFromSuperview];
[self release];
}
The changeIcon just sets the image to a corresponding icon.
As you can guess, this is not working - the changeIcon message never works.
I can't understand what am I doing wrong, any help much appreciated!
You have a few choices here...
First one is create a property on your IconsViewController of type ParentViewController*, for example:
#property (readwrite,nonatomic,assign) ParentViewController* parentController; // weak reference
To break this down further:
readwrite because we want to be able to access the value via [self parentController] but also change it via [iconsViewController setParentController:self]
nonatomic because I'm not too worried about threading
assign to make it a "weak reference" where the parent will not be retained by the child. If they each retain the other, it could lead to memory leaks later because unless explicitly released you'd end up with a retain circle causing neither object to hit a zero retain count.
When you load from nib, set the property:
IconsViewController *iconsViewController = [[IconsViewController alloc] initWithNibName:#"IconsView" bundle:nil];
iconsViewController.parentController = self;
Then, call to it from inside of iconIsSelected like this:
[[self parentController] changeIcon];
Alternatively, you can create a delegate protocol:
#protocol IconViewSelectedDelegate (NSObject)
- (void) changeIcon;
#end
And use that protocol as a property, instead of the parent view controller type. This is more abstract, but it keeps the design cleaner. The parent view controller would then implement that delegate protocol, as one of many others.
Another option is to use NSNotificationCenter and publish/subscribe to events from your dynamic view. This is the "loosest" coupling between the two objects, but it might be overkill for this scenario.
The superview of a view is a view, not a view controller, yet you cast the superview to be of class ParentViewController. If the view has no superview, it returns nil, and message to nil are no-ops (which explains why you don't crash there).
BTW, that [self release] at the end is highly suspicious.
im trying to implement some behaviors when a mapview element scrolls... by coding a delegate for the scrollview inside of a mapview.
so, right now, i got a pointer to the scroll view used by the map view in my code.
however, i wish to set the delegate of this scroll view inside the map view, but the issue is that the mapview already sets up a default delegate for this scroll view inside the map view.
can i make my delegate implement all of the messages of the protocol, explicitly sending them to the mapview's default delegate while also implementing my own behaviors?
how else can i go about adding my own delegate behavior, to an already existing default delegate....?
thanks everyone,
michael
You could just get the existing delegate and save a reference for yourself:
origDelegate = [theView delegate];
And then set the object you want as the delegate:
[theView setDelegate:self];
Then when getting a delegate message, call the same method on origDelegate, modify the response if you want to (or if necessary), and then return the modified response:
- (BOOL)shouldViewDoSomething:(id)theView
{
BOOL result = [origDelegate shouldViewDoSomething:theView];
if (decision1)
{
result = !result;
}
return result;
}