Add a subview from within and below another subview - ios

In an iOS app, I am adding a subview to my main view with:
[self.view addSubview:firstUIImageSubview];
However in the subview class firstUIImageSubview, I am creating and adding another subView (secondUIImageSubview) that I would like to put below the first subview with:
[self insertSubview:secondUIImageSubview belowSubview:self];
My problem is that the second subview is displayed above the first subview when I want to have it below. How is it possible to achieve that ? Thanks.

This should do the trick.
[self.superview insertSubview:secondUIImageSubview atIndex:0];

When you use insertSubview:belowSubview: it places the subview in regards to other subviews that particular object manages.
[self insertSubview:secondUIImageSubview belowSubview:self];
Doesn't make much sense. Although self is a UIView (or a subclass) it still should never manage itself as a subview. Therefore
[self insertSubview:secondUIImageSubview belowSubview:firstUIImageSubview];
is probably what you want. But remember this will only place the secondUIImageSubview below firstUIImageSubview in terms of its Z-Index (it's depth on the screen). If you want it to be physically placed below firstUIImageSubview (IE it's XY coordinate) then you need to set it's position using subview's frame or setting its origin instead (by manipulating it's center or anchor points for instance).

Related

MKMapView not responding to touch events or gesture recognizers

EDIT:
Immediately after posting this question, I found ONE line of code I missed commenting out. It was this... mapViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
I commented it out, and the map is working again.
Do you have any idea why that line of code would kill the maps gesture recognizers?
I have an MKMapView that was working perfectly fine in recent months, and quit dead today.
The only thing I did today, messing with the code, was to play with some orientation code in viewWillTransitionToSize:withTransitionCoordinator: and viewWillLayoutSubviews That's IT !!!
I commented out everything I did there, and still it's dead.
It not only won't respond to my own gesture recognizer, it won't respond to any of its own recognizers... pinch, rotate, etc. It's just frozen.
I have NO views on top of the map that would obstruct touches either.
I have control-clean(ed) my build folder.
I have closed XCode project and wiped out it's derived data folder for said project.
#implementation MapViewController
{
MKMapView *appleMapView;
}
-(void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self addMapViewToSelf];
}
-(void)addMapViewToSelf
{
// Create and add the apple map view to the side menu view.
appleMapView = [[MKMapView alloc] initWithFrame:self.view.frame];
[self.view addSubview:appleMapView];
appleMapView.delegate = self;
UILongPressGestureRecognizer *tapRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(windowTapped:)];
tapRecognizer.minimumPressDuration = 1.0f;
tapRecognizer.delegate = self;
[appleMapView addGestureRecognizer:tapRecognizer];
}
-(void)windowTapped:(UIGestureRecognizer *)recognizer
{
NSLog(#"The recognizer state is '%ld'", (long)recognizer.state);
if (recognizer.state != UIGestureRecognizerStateBegan) {
return;
}
}
AutoResizingMask is the property by by the UI Elements (eg. Label) shift when the boundaries change. Means when orientation is change the app adapts and does not crash. But if you will set autoResizingMask to Constraint, you are telling it to change constraints as per the autoResizingMask. This is the default behaviour of every UI Element. This helps us to quickly and dynamically arrange UI Elements with methods like self.view.centre or self.view.frame or self.label.size.width etc.
Setting translatesAutoresizingMaskIntoConstraints = NO you are actually removing this behaviour. Therefore you must provide the UI Element fixed co-ordinates, so that the UI Element stays there no matter the orientation of screen. But you are not doing so. So the UIElement has no constraints or a fixed location and behave erractically.
You must not set it to NO, if you don't want to play dynamically with UI's location or size. Like input based growing textfield or some crude animation.
Here is Apple trying to tell you the same thing.
When a view’s bounds change, that view automatically resizes its
subviews according to each subview’s autoresizing mask. You specify
the value of this mask by combining the constants described in
UIViewAutoresizing using the C bitwise OR operator. Combining these
constants lets you specify which dimensions of the view should grow or
shrink relative to the superview. The default value of this property
is UIViewAutoresizingNone, which indicates that the view should not be
resized at all.
When more than one option along the same axis is set, the default
behavior is to distribute the size difference proportionally among the
flexible portions. The larger the flexible portion, relative to the
other flexible portions, the more it is likely to grow. For example,
suppose this property includes the UIViewAutoresizingFlexibleWidth and
UIViewAutoresizingFlexibleRightMargin constants but does not include
the UIViewAutoresizingFlexibleLeftMargin constant, thus indicating
that the width of the view’s left margin is fixed but that the view’s
width and right margin may change. Thus, the view appears anchored to
the left side of its superview while both the view width and the gap
to the right of the view increase.
If the autoresizing behaviors do not offer the precise layout that you
need for your views, you can use a custom container view and override
its layoutSubviews method to position your subviews more precisely.
I do such mistakes a million times , this blog has a nice solution to it.
https://www.innoq.com/en/blog/ios-auto-layout-problem/

How to add UIView to the CorePlot view?

I have a UIView for CorePlot and I want to add UIView under the plot as a subview. I have tried this:
[self.view bringSubviewToFront:_viewTable];
But it doesnt work. How can I make it work?
EDIT:
My Storyboard:
Green - firstPieChartView (CorePlot view)
Red - UIview with tableView
In viewDidLoad:
[self.firstPieChartView addSubview:_viewTable];
[self.firstPieChartView bringSubviewToFront:_viewTable];
Do not add subviews to a Core Plot hosting view. The iOS hosting view applies a flip transform to its children so Core Plot can share drawing code with the Mac version. Instead of making your view a subview of the hosting view, make them siblings (i.e., children of the same parent view).
You are bringing the view to front by this, not adding it as a subview. First you have to use:
[self.view addSubview:yourSubview];
--in order to add it. Then you can bring it to front, if you're overlaying it with other subviews.

UIViews revert to a previous position after adding a subview

Facing a really strange issue trying to dynamically add a left navigation panel to a View Controller, (should be able to support any view controller in the app, vaguely similar to the Facebook navigation) My idea seemed fairly simple, but I'm really not seeing where it's breaking down. What I've done is created a Category on UIViewController with the following method which I would think would move all the subviews to the right, and then add the new view.
-(void)addLeftView:(UIView *)newView
{
newView.frame=CGRectMake(0, 0, newView.frame.size.width, self.view.frame.size.height);
for(UIView *view in [self.view subviews])
{
view.frame=CGRectMake(view.frame.origin.x + newView.frame.size.width, view.frame.origin.y, view.frame.size.width, view.frame.size.height);
}
[self.view addSubview:newView];
}
What actually happens, though, is that the view is added, but the subviews do not move to the right. However, if you comment the addSubview out, everything actually does move to the right exactly as expected.
To make matters even weirder, if you wrap the view movement in a [UIView animateWithDuration:completionHandler:], where the completion handler adds the subview, the animation actually happens - all the views shift to the right, but when the subview gets added, they jump back to their starting position.
I assumed this was some sort of wacky auto-layout issue, so just to see what happened, I cleared all the constraints out of that view controller, and get the same result.
Found the answer in a similar but un-related thread. Can I disable autolayout for a specific subview at runtime?
Basically it was auto-layout reverting my positioning, so disabling it by setting this user variable on just the UIViews of problem fixed my issues.
You can set the translatesAutoresizingMaskIntoConstraints type Boolean, Value to Yes in the User Defined Runtime Attributes of the UIView you want in the xib/storyboard.

UIView center X UIImageView

In one UIVIew i have 5 icon (UIImageView). I show/hide icons. Its ok. But i want if i hide 2 icon the rest what not hidden (or not removed) show center of the View.
if show all:
http://sherad.info/elotte.jpg
I remove from view 2 icon (i try the set hiden but the effect same)
[share removeFromSuperview];
[sms removeFromSuperview];
After this:
http://sherad.info/utana.jpg
I want the 3 icon show in center of view. So somehow re arrange the icons inside the UIView. How i can solved this?
thx.
I'll assume the black area behind the icons is a UIView and the icons have been added to it in a static position? What if, instead, you created a second UIView that was transparent. Determine what icons you want to display and add them into the second view. It would start off with the second view being the exact same size as the first view, but once you want to display less, remove all the icons from the second view
for (yourIcon *icon in [secondView subviews]) {
[icon removeFromSuperview];
}
reset the frame of the second view to be the length you want and re-add the icons, then place it in the center of the first view
secondView.center = firstView.center;
and either do
[secondView setNeedsDisplay]
or re-add it as a subview of firstView if you previously removed it (which I don't believe is necessary).
The subviews should position themselves relative to each other based on how many other icons there are. Every time there is an event that add or removes an icon you should call some layout code that will make the icons postion themselves.
Removing a view should have the superview count the added subviews, create new x coordinates based on the screen width divided by the count and then set the frames of all of the subviews.
There is probably a way to do this with autolayout but I'm not familiar with those methods.

I don't fully understand sendSubviewToBack. Please, see the code

You can see my screenshot of xib's file.
I do some manipulation in viewDidLoad
-(void) viewDidLoad
{
[smallView removeFromSuperview];
[bigView sendSubviewToBack:smallView];
}
Will the hierarchy change from view->bigView->smallView to view->smallView->bigView?
No the hierarchy will not be affected. The documentation says:
sendSubviewToBack:
Moves the specified subview so that it appears behind its siblings.
It changes the order of painting subviews. If you have two views which are overlapping and have the same superview then you will be able to define which of that two views should be in front.

Resources