Looping Through UIScrollView and Setting UImageView - ios

I am trying to implement lazy loading of images in a UIScrollView but I am having some problems trying to set the images.
The user scrolls and I use the following to detect what the next view tag should be. I then want to be able to loop through the corresponding UIView and set its UIImageView image.
The following is not working and I was hoping someone could help me to correct it.
for (UIView *subview in self._scrolViewForEffects.subviews){
for (UIImageView *view in subview.subviews){
if([view isKindOfClass:[UIImageView class]]){
if(view.tag == currentPage){
if(view.image == nil){
[view setImage:[UIImage imageNamed:#"Theme1.png"]];
}
}
}
}
}

It is not enough information to say what problem you can have but I suggest you to execute in debugger window a command
po [self._scrolViewForEffects recursiveDescription]
to check your view hierarchy at runtime.

Turns out that it wasn't to do with the code above. It turns out that I wasn't setting the tag on the UIImageView when I was creating it.
Thanks for the help!

Related

iOS XCode Add the scrollbar indicator program programmatically

I'm currently coding a iOS apps that contains a scrollview in the mainview. When the user want to reset the scrollview I'm running this method:
-(void)clearFlightTimer{
// Removing object (button, label and image) from subview
// *** KNOWN BUG WHEN REMOVING UIImageView OBJECT IT'S ALSO REMOVING THE SCROLLBAR IMAGE ***
for(UIView *subview in [self.flightViewScrollView subviews]) {
if([subview isKindOfClass:[UIButton class]] || [subview isKindOfClass:[UILabel class]] || [subview isKindOfClass:[UIImageView class]]) {
[subview removeFromSuperview];
} else {
// Do nothing - not a UIButton or subclass instance
}
}
// Reloading the View
[self viewDidLoad];
[self viewWillAppear:(YES)];
}
The issue is that the scrollbar seem to be part of UIImageView class and this method remove it. How could I keep the scrollbar image when removing all object from this subview? Is there a way to code the scrollbar indicator back programmatically?
Thanks!
Hope that I'm clear!
The simplest and most fool proof way is probably to add an intermediate subview of the scroll view that contains your actual content. This new container view's subviews can be iterated over and removed as you need. Alternatively, if you know the scroll view is in an empty state, you might be able to iterate over subviews of the scrollview and store all image views that exist when empty - those views will be the ones you shouldn't mess with.

UIPanGestureRecognizer + UIViewController

I am adding a UIPanGestureRecognizer to a partially hidden UIViewController (it is there to pull it back on screen). All is working fine except on the odd occasion when the UIViewController has a scrollable subView (i.e. UIScrollView, UITableView). I can't set useInteractionEnabled = NO because this disables my gesture... Any suggested workarounds?
EDIT:
I have this work around and it is achieving what I want...
for(UIView *subView in sender.view.subviews) {
[subView setUserInteractionEnabled:NO];
}
But I feel there should be a better solution?
The best I have come up with is
for(UIView *subView in sender.view.subviews) {
[subView setUserInteractionEnabled:NO];
}

How can I keep an UIimageView on top of other uiimageviews when using pan or other gestures

I have a ViewController on which I can move multiple UIImageViews using gesture recognizers. it's working fine but the UIImageView selected is not on top of the others.
The UIImageViews keep the order of their creation so the last ones are always bellow the first ones.
Any advice?
When you've selected your new UIImageView - from your UIViewController you should call:
[self.view bringSubviewToFront:imageView];
That should help.
You can use,
[superView bringSubviewToFront:touchedview]; for bringing the subview to the front
What you need to do it programmatically reorder them . You can do this in the following way
-(void)bringTheDesiredImageViewInFront:(int))_tagForImageView
{
for(UIImageView *_subView in self.view.subviews)
{
if([_subView isKindOfClass:[UIImageView class]])
{
UIImageView *temp=(UIImageView *)_subView;
if([temp tag]==_tagForImageView)
[self.view bringSubviewToFront:temp];
}
else
continue;
}
}
Call this method whenever the selector for any gestureRecognizer is called on any UIImageView . Also set the different tag values for different UIImageView . The above method could be called like this ,
UIImageView *imageView=[[UIImageView alloc] init];
[imageView setTag:1];
[self bringTheDesiredImageViewInFront:imageView.tag]

Maps and legal mention

With iOS < 6.0 we were able to re-position the "Google" link over map view (by browsing the subviews of map view). Now with iO6, there's a "legal" link and this is a MKAttributeLabel. A private class that we can't manipulate ...
My problem is that I must add a footer subview to my map and it'll hide the legal link ...
How can I solve this problem without any App Store rejection ?
Can I create another legal button my self and add it where I want in my map view ?
I have no idea what I'm able to do...
There's a few answers recommending you move the legal label in the viewDidAppear of your view controller, however this doesn't work if you then resize your map view (like I am).
The best way is to subclass the MKMapView and override the layoutSubviews method. In my example I just needed to nudge the legal label above a semi-transparent toolbar.
-(void)layoutSubviews
{
[super layoutSubviews];
UILabel *legalLabel;
for(UIView *view in self.subviews)
{
if([view isKindOfClass:[UILabel class]])
{
legalLabel = (UILabel *)view;
break;
}
}
legalLabel.center = CGPointMake(legalLabel.center.x, self.bounds.size.height - 55.0f);
}
Does the footer view have to be inside the map boundary, why not put the map and the footer into the same super view?

iOS: setting Exclusive Touch to all buttons in a view

My app has many buttons in a Window and I want to set Exclusive Touch all of them together. Do you have any suggestion about this? Thanks
There is a way to set exclusive touch to all buttons in your app, may be helpful.
#import </usr/include/objc/objc-class.h>
static IMP gOringinalWillMoveToSuperview = nil;
static id newMoveToSuperviewPlusSettingExclusiveTouch(id self,SEL selector,...)
{
va_list arg_list;
va_start( arg_list,selector);
gOringinalWillMoveToSuperview(self,selector,arg_list);
[self setExclusiveTouch:YES];
return nil;
}
-(void)addSettingExclusiveTouchToAllUIViewMethodWillMoveToSuperview
{
gOringinalWillMoveToSuperview = class_getMethodImplementation([UIButton class], #selector(willMoveToSuperview:));
class_replaceMethod([UIButton class], #selector(willMoveToSuperview:), &newMoveToSuperviewPlusSettingExclusiveTouch, "v#:");
}
if you don't understand this, you can refer to this and this.
Are you just looking for an easy way to set them all at once?
If you have all the buttons in an array (e.g. they're all connected to the same IBOutletCollection) you can use key value coding to set the exclusiveTouch property of the array:
[buttonArray setValue:[NSNumber numberWithBool:YES] forKey:#"exclusiveTouch"];
NSArray will then invoke the same method on every item in the array.
-(void)setExclusiveTouchForButtons:(UIView *)myView
{
for (UIView * v in [myView subviews]) {
if([v isKindOfClass:[UIButton class]])
[((UIButton *)v) setExclusiveTouch:YES];
else if ([v isKindOfClass:[UIView class]]){
[self setExclusiveTouchForButtons:v];
}
}
}
then call this function at viewDidAppear
If these buttons are all in the same view, you can loop through the view's subviews, test for whether the particular subview is a button (or test for a tag if you have one set) and set exclusiveTouch on each.
I just found an answer for this:
#pragma mark Set Buttons Exclusive Touch Yes
-(void)setExclusiveTouchForButtons:(UIView *)myView
{
for (UIView * button in [myView subviews]) {
if([button isKindOfClass:[UIButton class]])
[((UIButton *)button) setExclusiveTouch:YES];
}
}
Source
If you want to set exclusiveTouch for ALL UIButtons in your whole application method swizzling will be the perfect solution for you.
This answer explains the way very well : https://stackoverflow.com/a/24534814/976246 , and it works perfectly for me.
Also go through this article to know how this (http://nshipster.com/method-swizzling/) tecknique can be used for various purposes.
If you are adding buttons pragmatically, then send a message to the button [button setExclusiveTouch:YES]; for each buttons before adding to its super view. Else if you are using xib, you have to send the same message to the button in viewDidLoad or in loadView.
Here is some code in swift that will set exclusive touch to all buttons in your viewcontroller's view
for button in self.view.subviews {
if(button.isKindOfClass(UIButton)){
(button as! UIButton).exclusiveTouch = true
}
}
Even though the question was asked many years ago, here is a simple way to set isExclusiveTouch for all subviews that are buttons. This example shows code for subviews of self.view. Change self.view to your view of interest.
Seems like cleaner code for anyone with questions on this in the present.
for subview in self.view.subviews
{
if subview is UIButton {
subview.isExclusiveTouch = true
}
}

Resources