I added a ViewController to an app for ad banner support. The app was based on a UINavigationController so I added the ViewController as a subview to the UINavigationController. Now the area of the ad banner does not recognize when it is touched to open the ad in safari. I have tried to make the ViewController becomeFirstResponder but that doesn't work. Does anyone have any thoughts on how to fix?
you say you added it as a subview, but I hope you mean you pushed it with
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
Your view controller can respond to events because it is a UIResponder. UIView and therefore most visual controls like UIButton, UISlider etc. inherit from UIResponder also - but they implement specific actions based on user interaction.
If you really want to intercept events in a UIViewController you will need to handle touchesBegan/Moved/Ended events. More likely you have at least a UIWebView or UIImageView in the view controller if it is displaying something you want to click on.
If UIWebView you'll need a UIWebViewDelegate implementing
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
will let you know what links are being opened.
If a UIImageView you will also need to set the property userInteractionEnabled before you see any touch events.
If you're dealing with iAd's AdBannerView class, that inherits from UIView also, so comments for UIImageView apply. HOWEVER ADBannerViewDelegate is a requirement for built-in interaction support - just like UIWebViewDelegate, you must implement a permission/notification function,
- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
Related
Is it possible to call a method when a tab bar icon is touched, even if its already the selected icon? I want to make it remove a sub view when touched if the subview is showing.
I'm sure there must be a way to do this because I see it in other apps, but I cannot find any documentation on it.
From Apple Documentation for UITabBarDelegate :
- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
Sent to the delegate when the user selects a tab bar item. (required)
As you noticed I think, and as stated by Apple docs, this message is sent only when a tab is selected
An important note, there is already a (not-documented?) default UIKit behavior of tapping a selected tab bar button :
If the tab contains a UINavigationViewController it will send to it a popToRootViewControllerAnimated: message. You can check this on any iOS application.
So beware before overriding this default (and user expected) behavior, which is, generally, a bad idea.
Apple has probably hidden what you want to do in its UIKit API, on purpose.
But if you want anyway does this, here are some ideas:
Small, but not easy hack: Once the tabBar has been displayed, recursively browse its .subviews tree to find (I expect, to be confirmed) UIButtons inherited classes (=private UITabBarButtons or something like) to add your target/selector pairs on TouchUp event (you might have to remove default behavior first, which might be tricky)
Worst solution, but might be the only one: Do not use UITabBar, but a custom class. I'm pretty sure there are ready-to-use open source components that mimics UITabBar, but sorry, I never used/searched one.
You can have delegates for the UITabbarcontroller,
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0);
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;
Also please go through this document: UITabBarController delegate protocol
i need to add NSViewBoundsDidChangeNotification to my iphone application to check if user has scrolled the tableview,however to add this i think i need to import the nsview class.from where should i add this class to my project.and i need to confirm is this the best way to check if my tableview is scrolled by user?
NSView does not exist on the iPhone, as it uses Cocoa-Touch and not Cocoa.
If you want to get notifications about a UITableView's scroll events, just implement the UIScrollView delegate. It's documented here.
The delegate method you'll want to use is this one:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
}
There are other handy methods in there though, like:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale{
}
NSView has nothing to do with IOS development.
UITableView is a subclass of UIScrollView, and UITableViewDelegate conforms to UIScrollViewDelegate. This means that the delegate you set on your UITableView will get all the calls defined for UIScrollViewDelegate, including scrollViewDidScroll:.
So here is my dilemma, I have a navigation controller that controls three views. The first view has audio on it, the second view image sequences/videos and the third view will have audio.
How can I make sure that all of those things are ended (or just end them) when someone clicks the "Back" button to go to a lower numbered view?
media player classes, like audio and video, usually have "stop" methods that will do the trick. You can hook in to the viewWill/Did/Appear/Disapper methods on UIViewController to know when a view is/did become(ing) visible/invisible and stop the media playback at that time. I also like to put put "stop" method calls to media players in viewWillUnload and dealloc.
Make yourself the delegate of the UINavigationController and implement this:
- (void)navigationController:(UINavigationController *)navController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// Pseudo Code Here
[audio stopPlaying];
}
Look at UINavigationControllerDelegate. It has needed methods.
It appears that all the touch methods of a UIView are only called if the touches began within the bounds of that view. Is there a way to have a view respond to a user who has touched outside the view, but then dragged his fingers into the view?
In case it matters, my specific application is for dragging a MKPinAnnotationView (using built-in 4.0 dragging). I want something to happen if the user drags a pin onto another view (which happens to be an AnnotationView as well, but it could be anything). No method for dragging is called until I let go of the pin; and no method no the UIView that's being dragged to seems to be called unless I started by touching from within the view.
Because the superview is a MKMapView, it is difficult to just use the touchesMoved event of that and check if the user is in the right location or not. Thanks!
So after playing around with it for a while, I found that the answer given here actually gave me what I needed, even though the question being asked was different.
It turns out you can subclass UIGestureRecognizer; and have it handle all the touches for the view that it has been added to (including an MKMapView). This allows all the normal MKMapView interactions to still behave without any problem; but also alerts me of the touches. In touchesMoved, I just check the location of the touch; and see if it is within the bounds of my other view.
From everything I tried; this seems to be the only way to intercept touchesMoved while the user is dragging an MKAnnotation.
You sure can:
(HitstateView.h)
#import <UIKit/UIKit.h>
#interface HitstateView : UIView {
id overrideObject;
}
#property (nonatomic, retain) id overrideObject;
#end
(HitstateView.m)
#import "HitstateView.h"
#implementation HitstateView
#synthesize overrideObject;
- (void)dealloc {
self.overrideObject = nil;
[super dealloc];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *hitView = [super hitTest:point withEvent:event];
if (hitView == self) {
return overrideObject;
}
return hitView;
}
#end
Make this view the size of your touch area. Set the overideObject to the view you want the touches to go. IIRC it ought to be a subview of the HitstateView.
Every view inherits UIResponder so every view gets touchesBegan/Moved/Ended - I do not think starting the touch outside the view means the view gets no event when the touch moves over the view. If you want to get a notification that something has been dragged onto your MKMapView you should make a subclass that handles the touch but then passes the event to super, allowing the hierarchy to do whatever it needs to do with the touch. You don't need to capture or modify the event just observe it.
It depends on how your views are set up. Generally leveraging the responder chain is the best way to go. It allows you to play tricks, though it may be too specific to address your particular needs.
You can also play tricks with forward events by override hit testing:
http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MultitouchEvents/MultitouchEvents.html%23//apple_ref/doc/uid/TP40009541-CH3-SW3
Your particular case sounds pretty exotic, so you may have to play tricks like having a parent view whose frame is large enough to contain both views in question.
So I wanted to make my UIWebview respon to touch events. I have read several topics about this. I created a Subclass of UIWebView, added it so my UIViewController and linked it via IB.
In my Subclass, i overrode touches ended and called [super touchedEnded]. didnt help.
I overrode hittest, but it doesnt call super either!
If I add this code to my subclassed UIWebView:
#implementation UIWebView (CustomView)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
NSLog(#"hit");
return self;
}
#end
then the touches ar forwarded to the superclass, but hittest is not(!)and additionally the webview stops scrolling.
Well, I want so recognize a touch in my webview and pass it to super - what am I doing wrong?
EDIT:
I'm wondering, why so many suggestions include using 'hittest' - this results in being unable to scroll your webview.....any ideas?
Answering my own question here - this is the version that did what I wanted: The right way. This is about subclassing UIWindow and passing on the events caught.
I would still love some explanations to my previous questions tho :P