Swapping UIViews in and out of a ViewController's view - ios

I'm not entirely new to iOS/Swift development but I've mostly been working on "backend" code so my UI design/development skill level is unfortunately not what I'd like it to be. With that in mind, I have a UI layout (for a view controller) that looks something like this:
In this layout, the view labeled "View To Swap" could be in one of three states:
It may be hidden (or removed?) in which case StackView B should appear directly below StackView A
It may need to show (or be replaced by?) "Subview A"
It may need to show (or be replaced by?) "Subview B"
Both Subview A and B will have a button in the upper right hand corner that, when clicked, should remove/hide the "View To Swap" view.
I've been reading about container views a little bit and I'm wondering if this is the approach that I should take here or is there a more simple, direct way to implement this? I'm currently using the storyboard and autolayout to define my primary view (the view on the left) and constraints but I understand the basics of building a UI programatically if that makes it easier to implement something like this? Thanks for any suggestions!

You need to insert the 3 main views ( top stack , viewToSwap , bottom stack ) inside a vertical UIStackView with distribution = fillEqually , and hook viewToSwap as IBOutlet, whenever you want to hide it do
self.viewToSwap.isHidden = true
this will automatically collapse it's content , and you can add any subview to it (A/B) and don't forget self.viewToSwap.clipsToBounds = true

Related

How to bring subview to front in interface builder without changing its position

I want to ask a simple question how can I temporary bring a subview to front to view its element without changing its position by dragging and dropping. The problem i face all the time is i forgot to put the views back to there position and that causes lot of trouble specially if you are working on the view that have large number of subviews.
Question : Is there any shortcut or any functionality that can show the view temporary without dragging, changing its frame or making any changes in its hierarchy.
For a view controller like this :-
FYI, for those who are wondering, the view closest to the bottom of the list (on the left) will show in the front. So in the case below, view 'a' will be in front of 'b' and 'b' will be in front of 'c'
XIB:
If you need your views to be readily accessible for viewing/editing without having to rearrange them, I would actually recommend breaking them out into their own view and then stitching them together in the correct order in your code. This will ensure that all elements will be put in the proper order and will always be easily editable. Something like this:
And then in your code, in somewhere like viewDidLoad:
[self.view addSubview:view2];
[self.view addSubview:view3];

How to make Popup via storyboard(xib?) and programmatically Xamarin.iOS

For some reason i want to know how exactly i can implement Popup in Xamarin.iOS via storyboard and programmatically.
At current moment, i'm doing pretty simple workaround:
Inside designer, i'm dropping additional view(as popup) and configure like that
MyPopupView.Hidden = true;
After some steps(nvm), i'm showing this popup via
MyPopupView.Hidden = false;
And the result is :
Yeah, that is bad and very poor approach, because what if need these 5 guys or more ?
I will not be able to design my ViewController, because it will be stuffed with these views.
Also, for some reason i want to show arrow(see img below) and shadow(outside of popup) for better usability.
That what is exactly i want to do :
or this one(but inside, i want to put for e.g. my xib or VC,where i can drop some other views, like .gif animation):
or this one:
and finally, what i want(this one is amazing) :
Main idea to use storyboard(to make life easy with working on constraints and autolayout),but maybe it can be done programmatically the same.
I think that is possible to do that with UIAlertController , just needs to insert our View , but dunno is that right approach.
Thanks for any advice.
The last two images you posted can be accomplished using storyboards.
Essentially what you to do is create a separate scene/view controller in your storyboard and set it's presentation property to "over current context".
Alternatively you can set the segue to "Show modally" and the presentation property of the segue to "over current context" in Xcode
(for some reason the "Over current context" option doesn't come up in Xamarin Studio (at least not in Xamarin Studio 6) and when you open it back up in XS it will display a "Error while creating this entry" message by the presentation property but it should still work).
The next step is to set the root view to be transparent (background color = clear color) and then have a child view with your content.
If you want the semi-transparent overlay affect then what you can do is have two "sibling" child views one with your content (same as before) and a second view which is constrained to the edges of the root view and has it's alpha property set to something less then 1.
And here's the result...

How can I bring a view in front of another view, in Swift?

Below are how my views are organized in IB, top->bottom when the app is started.
The user can do something to make "Category Table View Header" temporarily expand over "Name View" - however once doing so, the .TouchDown action assigned to "Category Table View Header" no longer works wherever it overlaps with "Name View" (i.e., the user can tap the header anywhere it doesn't overlap with name view and it still works).
I know that may be confusing, so I drew out some boxes. On the left is the original, right is after user action - problem is on the right the action on the red box only works if the user taps the bottom half, not the top half.
My guess is its because the header is lower in the view hierarchy than the name view, but it would be hard for me to change that without messing around with a bunch of constraints.
I also tried setting nameView.hidden = true, but that doesn't work.
If you want to bring a subview to the front, you can use:
SWIFT 4 + UPDATE
self.view.bringSubviewToFront(yourView)
SWIFT 3 UPDATE
self.view.bringSubview(toFront: yourView)
Send view to back:-
SWIFT 4+ UPDATE
self.view.sendSubviewToBack(yourView)
SWIFT 3 UPDATE
self.view.sendSubview(toBack: yourView)
SWIFT 4+ UPDATE - INSERT VIEW ON SPECIFIC LOCATION IN THE STACK
parentView.insertSubview(yourView, belowSubview: requiredViewOnStack)
parentView.insertSubview(yourView, aboveSubview: requiredViewOnStack)
Swift 5.1+
UIKit draws views back to front, which means that views higher up the stack are drawn on top of those lower down. If you want to bring a subview to the front, there's a method just for you: bringSubviewToFront(). Here's an example:
parentView.bringSubviewToFront(childView)
This method can also be used to bring any subview to the front, even if you're not sure where it is:
childView.superview?.bringSubviewToFront(childView)
In Swift 5
To bring a subview to front
self.view.bringSubviewToFront(yourView)
To send a subview to back
self.view.sendSubviewToBack(yourView)
You can take a control over the order of subviews using methods: bringSubviewToFront and sendSubviewToBack from the superview.
You can access all the subviews contained by superview using self.view.subview array.
The method has been updated since swift 3
What has worked for me and hopefully for you is using :
YourView.bringSubview(toFront: yourelementA)
YourView.bringSubview(toFront: yourelementB)
Alternatively you could use the following to send the object that is in the front:
YourView.sendSubview(toBack: yourelementC)
I hope this helps
Swift 5.4
views in UIKit are drawn from the back towards the front (like adding icing onto a cake). This means that the new views will be placed on top/over the previously placed views. (e.g. Icing is the new view and the base of the cake being the old view.
You can use the following to manipulate the views Z-position using,
Forward
parent.bringSubviewToFront(child)
Backward
parent.sendSubviewToBack(child)
bringSubViewToFront did not work in my case, Take a look
As I wanted this notification count comes before image, bringSubViewToFront did not work, So I just drag this label below to stack view of my imgae and bottom label, it worked for me.
I hope this will work for all

Drag and move something in Interface builder, without changing parent/superview

I have some views in interace builder. I have a background view that takes up my entire view area
and above it I have some buttons which are NOT in the background view.
I want to drag those around to reposition them; but when I do, IB will reparent them when I let go of them.
That is to say, IB seems to only understand drag/drop in this case as a reparenting action; not a moving action.
Is there a hotkey, or something I can do to make IB just move things, without changing the parent when I let go?
This has to be the most painful part of working with IB for me.
If you hold the command key down while dragging, the dragged element will not change superviews. At least in Xcode 7.3.
This has been bothering me as well. I've found a workaround which I find slightly less annoying. Sounds like a lot but it's really quite easy.
Select the item you want to move
Goto Editor -> Embed In -> View (this creates a parent view for your item)
Resize (but don't move) the parent view to encompass the area you want to move to
Move the item within the parent view
Select the parent view and Goto Editor -> unembed
Also, since resizing doesn't cause the parent to change you could actually move a view with two resizes. However it's tedious to get the size right again which is why I like the embed method.
You can press function key and drag the object: Fn + drag

how to redraw custom view from the controller in ios objective-c

I have a custom view with 3 buttons taking full width.
I import the class to my controller where I want to hide on button (menuBtn) and make one of the one of the other buttons (searchbarBtn) be bigger to fill the empty space by doing:
`self.topMenuView.searchbarBtn.frame = CGRectMake(self.topMenuView.searchbarBtn.frame.origin.x, self.topMenuView.searchbarBtn.frame.origin.x, self.topMenuView.searchbarBtn.frame.size.width + self.topMenuView.menuBtn.frame.size.width , self.topMenuView.searchbarBtn.frame.size.height);`
I do this in viewWillLayoutSubviews (have also tried in viewWillAppear) and I call the
[self.topMenuView.searchbarBtn setNeedsDisplay];
but nothings happens.
I
The button's layout properties override your frame settings, since by definition viewWillLayoutSubvies is called before the layout pass. You should just set
self.topMenuView.menuBtn.hidden = YES;
and use autolayout constraints (in the interface builder or in the code) between menuBtn, searchbarBtn and topMenuView to make sure your buttons grow as needed.
As a general rule, we should strive to create interface so that views will correctly position themselves provided their inner state is correctly set and correct constraints are formed, without explicit corrections on our part.

Resources