Dismiss a UIPopoverController - uikit

Is there a right mechanism to dismiss a UIPopoverController from the controller that I've passed in the ctor?
_popover = new UIPopoverController(myController);
From myController instance, I would dismiss the popover but I can't find any system UIViewController property to do that.
A fix is to create a public property in MyController class of type UIPopoverController and then set it when I create the _popover instance. But I think it's not so good.
myController.PopOverProperty = _popover;

_popover.Dismiss(true);
Do you need this?

Related

Access parent view from a chid UIView

I have a UIViewController with an xib and using Interface Builder I've added a child UIView.
Within the child UIView, when I click on an object within that view, I want to be able to alter the title of the whole window.
Now I'd normally do that setting
self.title = #"hi";
on the parent UIViewController. But is there any way I can access the parent title from within the child?
I've tried
self.superview.title = #"i";
self.parentViewController.title = #"hi";
but neither work.
Any help much appreciated
thanks
self.superview.title = #"i"; evaluates to an object of type UIView, and UIView has no title property. UIViewControllers have a parentViewController property but UIViews don't.
So the fundamental problem is that you're not properly separating your controller and your view classes. What you'd normally do is make the view you want to catch taps on a subclass of UIControl (which things like UIButton already are, but if it's a custom UIView subclass then you can just change it into a UIControl subclass since UIControl is itself a subclass of UIView), then in your controller add something like:
- (void)viewDidLoad
{
[super viewDidLoad];
// we'll want to know if the view we care about is tapped;
// we've probably set up an IBOutlet to it but any way of
// getting to it is fine
[interestingView
addTarget:self
action:#selector(viewTapped:)
forControlEvents:UIControlEventTouchDown];
// UIButtons use UIControlEventTouchUpInside rather than
// touch down if wired up in the interface builder. Pick
// one based on the sort of interaction you want
}
// so now this is exactly like an IBAction
- (void)viewTapped:(id)sender
{
self.title = #"My new title";
}
So you explicitly don't invest the view with any knowledge about its position within the view hierarchy or how your view controllers intend to act. You just tell it to give you a shout out if it receives a user interaction.

How to use custom Navigationcontroller in AppDelegate by using a Storyboard

I've got a problem concerning Navigationcontroller in AppDelegate. I'm using a storyboard, which looks like this:
As a result of using Push notifications, i've got the following function in my AppDelegate File:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
//...
}
When the notification arrives I want to initialize the "Detail View" - Controller which needs an ID as a parameter. This ID is part of my payload so it is present in didReceiveRemoteNotification.
I'd like to to the follwing:
DetailView *detail = [storyboard instantiateViewControllerWithIdentifier:#"detail"];
detail.conversationID = theID;
[self.navigationController pushViewController:detail animated:YES];
My question at this point is: how can I get the navigation controller? I've searched for a function like "getNavigationControllerByIdentifier" or something like this, but found nothing. I can't instantiate the Detail View Controller directly because the navigationbar is missing there.
I hope you understand what I mean - if you think my approach is completly wrong please correct me ;o)
Just another small information: It's not important for me that the back button in the Detail View Controller goes back to the Table View - it's enough when it links to the controller with the button "Load Table View".
Thank you for help!
UINavigationController is a UIViewController subclass and can also be assigned an identifier in the storyboard.
Use -instantiateViewControllerWithIdentifier: to create the UINavigationController and it's root view controller. You may need to instantiate all of the intermediate controllers in code and modify the navigation controller's viewControllers property to set up the appropriate navigation stack. This way when the app launches into the detail view, they can find their way back as if they had manually pushed all the way through via the interface.
You can use rootViewController on your window object.
UIViewController *rootViewController = self.window.rootViewController;
// You now have in rootViewController the view with your "Hello world" label and go button.
// Get the navigation controller of this view controller with:
UINavigationController *navigationController = rootViewController.navigationController;
// You can now use it to push your next view controller:
DetailViewController *detail = [navigationController.storyboard instantiateViewControllerWithIdentifier:#"detail"];
detail.conversationID = theID;
[navigationController pushViewController:detailViewController animated:YES];

Bind a custom control created as UIView in Interface Builder via monotouch

Using monotouch and monodevelop, I'd like to create a custom control.
I followed this steps:
add a new file as "iPhone View" (calling it TestView)
edit TestView.xib in Interface Builder, es. changing it's background and size
edit MainWindow.xib in Interface Builder, adding a UIView and setting it's class identity as "TestView".
At this point, I'd like to launch the application and see in the UIView of MainWindow the content of an instance of TestView.
In order to get this "binding" I tried several steps (I know it can be done via code creating the outlets, etc.., but I'd like to understand if it can be done via Interface builder).
In one of the methods tried, I set via Interface Builder the value "TestView" as class identifier in the View of TestView.xib: in this way MonoTouch created the code in TestView.xib.designer.cs.
[MonoTouch.Foundation.Register("TestView7")]
public partial class TestView7 {
}
Then, in TestView.xib.cs, I added:
public partial class TestView : UIView
{
public TestView (IntPtr p) : base(p)
{
}
}
When I launch the app, I cannot see in the view of MainWindow the content of TestView, but if in TestView constructor I add something such as
BackgroundColor = UIColor.Yellow;
then, I can see TestView in MainWindow... or better I can see only the yellow rectangle, not the real content!
So, the problem is that TestView is binded to the UIView in MainWindow, but it's content comes only from the code and not from the content defined via Interface Builder in TestView.xib.
Is there a way to load the content from the TestView.xib?
Take a look at http://ios.xamarin.com/Documentation/API_Design#Interface_Builder_Outlets_and_C.23
I believe what you need to do is add a constructor that handles the nib file (The following is from the above link):
When using MonoTouch your application will need to create a class that derives from UIViewController and implement it like this:
public class MyViewController : UIViewController {
public MyViewController (string nibName, NSBundle bundle) : base (nibName, bundle)
{
// You can have as many arguments as you want, but you need to call
// the base constructor with the provided nibName and bundle.
}
}
Then to load your ViewController from a NIB file, you do this:
var controller = new MyViewController ("HelloWorld", NSBundle.MainBundle, this);
This loads the user interface from the NIB.
The answer by Allison A in SO question monotouch - reusable iOS custom view, explains how to load existing composite views created in Interface Builder into a custom view.

Interface Builder for Dummies: How to set an action to an UIBarButtonItem in Xcode 4?

I am trying to set the action for a UIBarButtonItem I have in my MainWindow.xib. I keep going round and round and I'm not getting anywhere. My controller hierarchy is as follows:
UITabBarController
UITabBar
UINavigationController
UINavigationBar
UIViewController
UINavigationItem
UIBarButtonItem // THIS
UITabBarItem
How can I set the action to it? I see a "selector" option in IB, but I'm not sure how to set it.
So, based on your comment answer, you'll have to use the targetand action properties.
Target is the object that will receive the action.
Action is a selector (a method), from the target object.
myBarButtonItem.target = self;
myBarButtonItem.action = #selector( myMethod: );
Remember action method must have the following signature:
- ( IBAction )myMethod: ( id )sender;
The sender object will be the object that triggered the action, in your case the UIBarButtonItem.

Cocoa - calling a VIEW method from the CONTROLLER

Got a little problem i asked about it before but maybe i didnt ask properly.
I have a cocoa application, which amongst other things, must do the following task:
- load some images from the disk, store them in an array and display them in a custom view.
In the Interface Builder i have a CustomView and an OBJECT that points to TexturesController.h
The custom view is a custom class, TextureBrowser.
Below is the code for the controller and view:
TexturesController
#import <Cocoa/Cocoa.h>
#class TextureBrowser;
#interface TexturesController : NSObject {
IBOutlet NSTextField *logWindow;
IBOutlet TextureBrowser *textureView;
NSMutableArray *textureList;
}
#property textureView;
-(IBAction)loadTextures:(id)sender;
-(IBAction)showTexturesInfo:(id)sender;
#end
TextureBrowser
#interface TextureBrowser : NSView {
NSMutableArray *textures;
}
#property NSMutableArray *textures;
-(void)loadTextureList:(NSMutableArray *)source;
#end
These are just the headers. Now , what i need to do is:
when loadTextures from the TexturesController is called, after i load the images i want to send this data to the view (TextureBrowser), for example, store it in the NSMutableArray *textures.
I tried using the -(void)loadTextureList:(NSMutableArray*)source method from the view, but in the TextureController.m i get a warning : No -loadTextureList method found
This is how i call the method :
[textureView loadTextureList: textureList];
And even if i run it with the warning left there, the array in the view class doesnt get initialised.
Maybe im missing something...maybe someone can give a simple example of what i need to do and how to do it (code).
Thanks in advance.
In TexturesController.m, you have to import TextureBrowser.h so that the controller knows what methods the property textureView has. Right now, you've just got a blank placeholder symbol instead of an actual class.
Since textureView is defined by an outlet, you need to make sure that its class is properly set in Interface Builder. If you provide a generic NSView instead, it won't have the loadTextureList: method.
If you imported TextureBrowser.h in TexturesController.m, I don't see why it wouldn't find your method.
But why don't you simply call self.textureView.textures = textureList; from the TexturesController ?

Resources