How to tell when a subView is removed a UIView - iphone

Basically i wanted to implement a popup UIView so i followed what was posted here
POP-UP UIView "IMDB App" style
This works very well. However i have one query. My main view is a tableView. so when a view is popped up i disable scrolling in the table. Now when the popup subView is removed, i need to re-enable scrolling. How do i achieve that? i can't use willRemoveFromSuperview because the popup view is loading a different NIB altogether.
Should i use Notifications?
hope i was clear with explaining the scenario.
Thanks in advance!

Feloneous Cat has the correct answer. This is the perfect use a #protocol in your popup view along with a registered delegate. Something is triggering that popup view to close. Whatever that trigger is, call the protocol and the delegate can handle the situation as needed.
Furthermore, when protocols are used correctly, your code becomes very reusable within a project as well as in other projects.

What you could do is subclass UIView and override removeFromSuperview to send a notification. I don't think there's ever a case where a view gets removed without using the removeFromSuperview method.

Related

iPhone - a UIView that behaves like a UIViewController

I need to create a class that will present a UIVIew and has a some code to initialize it before it is ready to show. I need to know when the view is ready, I mean, I need something like viewDidLoad or viewWillAppear, but as it is a UIVIew it lacks these protocols.
I cannot implement it as a UIViewController as I don't want to present it modal. It is really a rectangular view that needs to show on a screen side.
How do I declare this class? If the class is a UIView based I don't have the methods I mentioned.
thanks
Any reason to not do that kind of stuff inside the initWithFrame method on a UIView? Also, you can do additional stuff on layoutSubviews. A view controller has viewDidLoad because the view is lazy loaded (from a nib or otherwise - it also has a loadView). It has viewWillAppear and viewWillDisappear because it is managing the view (btw, even the view controller is managed by another view controller - these methods are called when you have the controller within a UINavigationController or UITabBarController or such classes which mange UIViewControllers. - the view itself is not really managing anything. All it knows about is how to draw itself. For that, you have layoutSubViews, drawRect, etc.
Doing some heavy stuff upon view's load will definitely kill the UI performance. You probably need to implement another kind of design pattern that will asynchrounously assign data values to the instance of your custom view - when that is done, you call layoutSubviews or setNeedsDisplay to update the view.
The scenario you described is no reason for not implementing a UIViewController. Assume you have a container view A and a subview B. Both have their own UIViewController AC and BC. Now on AC you add the View B managed by BC:
[self.view addSubview:BC.view];
You probably want to be using UIViewController.
You don't just have to present them modally. You can get your view controller's view with yourViewController.view, and add that as a subview of whatever view you want.
If you're targeting iOS 5, there are a few new methods (such as addChildViewController:) designed to make doing things like this easier. You can do it on iOS 4 too though, and it'll still work.
Implement a drawRect in youR UIView, plus an initialization flag. Just before the view is to be displayed the drawRect will be called. If the initialization flag isn't yet set, do your initialization and set the flag. This will only look good if your initialization can be done quickly (no long synchronous calls).
I need to create a class that will present a UIVIew and has a some code to initialize it before it is ready to show. I need to know when the view is ready, I mean, I need something like viewDidLoad or viewWillAppear, but as it is a UIVIew it lacks these protocols.
You might want to rethink how your view is being used. It sounds like you're trying to put too much controller-like logic into your view. That's why you're wanting your view to behave like a controller.
More specifically: What exactly are you trying to accomplish? If you're waiting for data to load before display the view, that might actually be something to put in the controller that is calling the view.
To illustrate my point, imagine you're putting some text in a UILabel that you read from disk. The reading from disk isn't really related to the view. The view only cares what text it displays, not how it received the text. Once it's read from disk, you can create a UILabel with that text that you read. This allows the UILabel to be more flexible.
That example might not be at all related to what you're doing, but I use it as an example of the difference between a view and a controller. Anything not related with the display and drawing of the view shouldn't belong there.

Reload all subViews of current ViewController

I have a situation where i have to reload all subViews of my current view....I am adding all objects(like buttons, images ...etc) from interface builder.....
And i want to reset these subviews when user click on a button...
i tried [self.view setNeedsDisplay]; but it doesn't works.
Is there any simple way to do this...
Any suggestion?
I am not sure that what happening in your code but i guess
You should add all subview programatically and refresh on button click event,
or write code in viewDidAppear method.
Reloading them sounds like the wrong thing to do. You can easily reset them to their default state programmatically by setting the various properties to your defaults. Once you do that I would probably just create the whole view and subviews programmatically without using IB. I do everything programmatically now and find it easier to maintain my code.
You could come up with a NIB based solution by putting all affected subviews within a parent UIView and load just that parent view from a NIB and then replace the parent UIView only but I don't recommend it. You need to able to set subview properties programmatically in viewDidLoad anyway in case the view controller needs to unload/reload the view based on memory warnings.
May be this is helpful to you.
One way is create on UI method that set default or required value for required controllers. And call it on button event.

Full-screen UIView subclass as veil not consuming touch events

I have a tab bar app that works. Each tab is a UINavigationController whose root view is some kind of UIViewController, often a UITableViewController.
There are instances in the app where I want to display a full-screen "veil" with a message about what's happening until some operation completes. The point is to swallow up any touches on the UI that would navigate away from where the operation started.
The veil is a UIView subclass. There is one singleton instance of the class. When displayed, I insert it as a subview of the UITabBarController view. The view appears over the entire UI, tab bar included. Great!
Here's the problem. I can tap the tabs and the UI changes. What I would have expected is that my veil view would have just swallowed up the touches.
I have implemented in my veil class the various touches{Began|Ended|Moved|Canceled} methods (as do-nothing methods), but the touches are still picked up by the tab bar, and frankly by any object under whereever I happen to touch.
I've also tried overriding a number of other methods including nextResponder, hitTest:withEvent:, etc, to no avail.
I am a little stumped at this point. I'm hoping someone will have some sage advise. :-)
Thanks.
It's not safe to modify the view hierarchy of framework classes. You would be much better-served simply adding it as a subview of the window itself. As for consuming touches, if making this change doesn't work, then you should also verify that userInteractionEnabled is set to YES on the view. You should not have to actually implement any touch-related methods.
I also had this problem and came up with a hacky solution. In the init of your custom UIView class, create a dummy UIView that's impossible to hit, for example [[UIView alloc] initWithFrame:CGRectMake(-1, -1, 0, 0)]. Or actually, I think any UIView not attached to the window works. Then, in hitTest:withEvent:, have it return the dummy view for every point not in your area of interest.

Where to add custom menu items to UIMenuController?

I created a subclass of UITextView and now I want to extend the default UIMenuController by adding some buttons. Performing the extension is no problem at all, I just need to add some UIMenuItem so the menuItems array of the shared instance of the UIMenuController.
My question is now: Where do I perform this manipulation? The MenuController is a singleton implementation, so every change I make will affect all the other views that support the menu. So where am I going to add the extra menu items and where do I later remove them again? I am searching for some kind of equivalent to the UIViewController's viewWillAppear method.
Or am I worrying way too much and it is perfectly good practice to implement it in the view controller of the view containing my UITextView subclass?
However, this means that every view controller containing my class as subview would have to implement the same code. Is there a better way?
Edit: Another option is of course to keep the selectors for my class unique and have all other custom views return NO for the selector in -respondsToSelector:. This seems to be the best solution so far to me.
What is the best practice?
It turns out that it works fine to add the items in the app delegate. You need to make sure of course, that other Views supporting the MenuController return NO for your particular selector in -respondsToSelector:.
Good question. Not sure about best practice.
You probably want to use the viewDidAppear and viewWillDisappear to modify that.

How to draw or put a text on empty an UITableViewController?

I have a app that starts with a empty UITableViewController, which is pretty .. well, emtpy. Now I was wondering if I could hint the user by painting something else on the view, like pointing an arrow to the plus button and say something like "press here to add something new"
I'll guess I have to do this in the viewDidLoad method, where I also init my NSFetchedResultsController, so I actually know if there are any objects in my list. I never put controls on the screen by code so I am not sure where to start and where to put em on. will that be the [self view] ?
Thanks
You could either try [tableview addSubview:xyz] or add it to the UITableViewController holding viewcontroller or you could (iphonestyle) add an add button to the NavigationBar.
I wouldn't direct the user to "press" anything, ever, on iOS. Use "tap" instead.
If you're using standard UI, you'll probably have a button that looks like [+], which is consistent enough across iPhone apps that your prompt should be unnecessary.
If you still want to add your prompt, I would subclass a UIViewController, implement the UITableViewDelegate and UITableViewDataSource protocols, and add a the prompt (which itself will be a subclass of UIView) to the view hierarchy of the controller.