I want to implement a function whereby a lock button is pressed which locks the current state of my app and prevents all scrolling and button pressing until the unlock button is pressed. I have no idea how to go about this please give me ideas and sample code! There is a similar function in the app GoodReader if anyone knows of this.
Thanks!
try something like:
for(UIView* subview in [self.view subviews])
if(subview != yourLockButton)
subview.userInteractionEnabled = NO;
Disable all the scroll in the view
- (void)disableScrollView
{
for (UIScrollView *view in your_viewController.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
view.scrollEnabled = NO;
}
}
}
Related
I am currently using MPVolume to stream audio from my app to Apple TV.
MPVolume has route button and I want to expand the touching area of this.
UIButton *button;
for (id object in self.volumeView.subviews) {
if ([object isKindOfClass:[UIButton class]]) {
button = object;
}
}
I use snippet code above to catch up this button and set the new frame for it but it does not work.
You can subclass MPVolumeView, override layoutSubviews method, on this method, find the Button and resize it.
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *view in self.subviews) {
if (view.class == NSClassFromString(#"MPButton")){
//Do something here
}
}
}
- (void)preventGADBannerViewBounceScrolling:(GADBannerView*)bannerView {
for (UIWebView *webView in bannerView.subviews) {
if ([webView isKindOfClass:[UIWebView class]]) {
webView.scrollView.scrollEnabled = NO;
webView.scrollView.bounces = NO;
}
}
}
I have been using the above code to stop the AdMob banner from scrolling.
I just updated the SDK to the latest (6.12.0) and having this code and calling it with the following...
[self.view addSubview:self.adMobBannerView];
[self preventGADBannerViewBounceScrolling:(GADBannerView *)_adMobBannerView];
Does nothing on the latest SDK, I was wondering if anyone has had this issue and resolved it?
Also when on this subject, I have noticed some developers have made their banners so if the user clicks then it opens up in a web view within the application and has a "Done" button at the right hand corner so the user does not fully leave the application when they press on the in-app adverts, I think that is genius...
If anyone could tell me how that is done I would appreciate that greatly!
It looks like UIWebView is wrapped into one more view in the new SDK, so it's better to go through the whole subview tree:
- (void)walkSubviewsOfView:(UIView *)v block:(void (^)(UIView *))block {
block(v);
for (UIView *subview in v.subviews) {
[self walkSubviewsOfView:subview block:block];
}
}
- (void)disableBannerWebViewBouncing {
[self walkSubviewsOfView:_bannerView block:^(UIView *v) {
for (UIGestureRecognizer *r in v.gestureRecognizers) {
if ([NSStringFromClass(r.class) isEqual:#"UIWebTouchEventsGestureRecognizer"])
r.enabled = NO;
}
if ([v isKindOfClass:[UIScrollView class]])
((UIScrollView *)v).bounces = NO;
}];
}
Of course this is not a future proof solution as well, I'd prefer there would be a corresponding property in the SDK.
I went with a non-block version of aleh's answer, I found it easier to read:
- (void)removeScrollingFromView:(UIView *)view
{
for (UIView *subview in view.subviews) {
[self removeScrollingFromView:subview];
}
if ([view isKindOfClass:[UIWebView class]]) {
((UIWebView *)view).scrollView.scrollEnabled = NO;
((UIWebView *)view).scrollView.bounces = NO;
}
}
I know I won't have any scrolling ads, but if you do, just disable bouncing and not scrolling. If you vote up my answer, please consider giving aleh a vote up too!
In my app I need to call some UIViews more than once. But in one of my method, i've a code like :
[self addSubview:UIImageView];
But i've read that addsubview method must be call once. So, to let the code how is it, how could I check if it's already on subview ? Like :
if ([UIImageView isOnSubview] == NO)
{
[self addSubview:UIImageView];
}
Because I don't find any method to check this :/
Thank you !
You are probably looking for UIView's -(BOOL)isDescendantOfView:(UIView *)view; taken in UIView class reference.
use this one
for (UIView *subview in [self subviews])
{
NSLog(#"%#", subview);
// ---------- remember one thing there should be one imageview ------
if(![subview isKindOfClass:[UIImageView class]])
{
[self addSubview:UIImageView];
}
}
I have some text edit fields, and also a button to show a uidatepicker.. if I go to the uitextedit, the keyboard appears, but when I click the button, the keyboard is still here...
how can I remove it?
thanks!
You need to use resignFirstResponder, see this similar question.
[myTextField resignFirstResponder];
See this answer for the easiest way to do it: Easy way to dismiss keyboard?
[self.view endEditing:YES];
Call -resignFirstResponder on your currently-editing text field.
There are cases where I don't have direct access to the 'first responder', so I tend to use a different approach.
I have a utility class for the keyboard with, among other functions, this one:
+ (BOOL)dismiss:(UIView *)view
{
if (view.isFirstResponder) {
[view resignFirstResponder];
return YES;
}
for (UIView *subView in view.subviews) {
if ([Keyboard dismiss:subView]) // It's calling itself, just to be perfectly clear
return YES;
}
return NO;
}
This lets me simply call for example: [Keyboard dismiss:self.view] from anywhere within a UIViewController.
(my boss says) that I have to implement a "Done" button on a navBar so that the various items in the view (that contain an edit box) will dismiss their keyboard (if they were in focus).
It seems that I must iterate through all items and then call resignFirstResponder on each on the off-chance that one of them is in focus? This seems a bit messy (and hard to maintain if e.g. someone else adds more items in future) - is there a better way to do it?
I have found it!
Thanks to this
I discovered that all I need do is this:-
-(void) done {
[[self.tableView superview] endEditing:YES];
}
// also [self.view endEditing:YES]; works fine
[remark]
Also I learn how to do the equivalent of an "eventFilter" to stop UITableViewController from swallowing background touch events by intercepting them before they get there - from the same, wonderful post on that thread - see "DismissableUITableView".
[end of remark]
You don't have to iterate through the controls since only one can be first responder at the moment.
This will reset the responder to the Window itself:
[[self window] makeFirstResponder:nil]
One solution is to use a currentTextField Object,
In .h file have an instance variable as
UITextField *currentTextField;
Now in .m file.
Note : Dont forget to set the delegates of all the textField to this class
- (void)textViewDidBeginEditing:(UITextView *)textView
{
currentTextField = textField;
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
currentTextField = nil;
}
Now in your button action method
-(IBAction)buttonTap
{
if([currentTextField isFirstResponder])
[currentTextField resignFirstResponder];
}
This avoids iterating through all the text field.
I think best way to handle it by searching all subviews of main view with recursive function, check example below
- (BOOL)findAndResignFirstResponder {
if (self.isFirstResponder) {
[self resignFirstResponder];
return YES;
}
for (UIView *subView in self.subviews) {
if ([subView findAndResignFirstResponder]) {
return YES;
}
}
return NO;
}
and also you can put this method to your utility class and can use from tap gesture. All you have to do is simply adding to gesture to view.
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(hideEverything)];
[self.tableView addGestureRecognizer:gestureRecognizer];
and than you can call hideEverything method;
- (void) hideKeyboard {
[self.view findAndResignFirstResponder];
...
...
}