Having a subview inside of another view - ios

My SCNView is full screen, but I would like to add a view in the bottom right corner like a minimap of a game. I have the code working separately in each of the views, but I have no idea how to view both of them at the same time.
If possible, I would also like it so that if the smaller view is touched, the position of the two views are swapped (the main view becomes the mini-view, and the mini-view becomes the main view) -- which could be repeated as needed to swap them out.

SCNView is a subclass of UIView so you can treat it like a regular view. There are too many different ways to handle this to cover them all. But for example, use addSubview to add one to the other. You could for example also use a popover view in the first scene, and add the minimap sceneview to the popover.
To swap them around you can use one master view (like the one of your main view controller) and then add the first sceneview, and to that sceneview add the mini map. When you tap the mini map you can simply remove them from their parents and add them again in the desired hierarchy. Another option would be to add both sceneviews to a master view and resize them and then use sendSubviewToBack on the sceneview that was the minimap.

Related

How do I add an overlay that does not move with the map to a GMSMapView?

I'm trying add a crosshair in the middle of a GMSMapView. The crosshair will not move with the map as the user pans it. It will move with the camera.
I looked at the google maps guide but it doesn't seem to talk about the kind of overlays I'm interested in. What it says is just adding overlays and shapes that moves with the map.
Therefore, I tried to come up with something on my own. I tried to add an UIImageView on top of the map view he storyboard. (Note that both the image view and the map view is in the storyboard and they are both direct subviews of the view that the VC controls)
When I run the app, I did not see the crosshair anywhere on the map. I looked at the UI hierarchy and saw this:
The little view is the image view with the crosshair, and as you can see there are 3 more views in front of it. I think this is why the crosshair did not show. The three views are, from right to left: GMSVectorMapView, GMSUISettingsPaddingView and GMSUISettingsView.
I have not idea how to bring the image view to front. I tried bring it to front by calling bringSubview(toFront:). I tried to call this in both viewDidLoad and viewDidAppear but it did nothing in both times.
How can I make such an overlay work?
You can use zPosition to achieve this
YourView.layer.zPosition = 1
by doing this you will put your view's layer to the frontmost position, but not the view itself. So position of the view won't change.
self.view.bringSubview(toFront: YourView)
Should also work, it's probably juat a timing problem.

how does one bring superview to front?

Normally developers try to bring subview to front. On contrary, how does one bring superview to front?
I'm looking for a reverse of bringSubviewToFront(_:). It should look like bringSuperviewToFront(_:)
I'm looking for a reverse of bringSubviewToFront(:). It should look like bringSuperviewToFront(:)
That doesn't exist. Instead of giving your button a subview, make both the subview and the button subviews of some container. Then you can adjust their relative z positions to suit your purpose.
I do not think you can do that. Views are laid down in layers with each sub view layer being part of super view layer. The effect you want to materialise can be achieved by hiding/removing all the sub views of the view you want to get Bring To Front effect on.
This works well with sub views because normally you would want to show/hide subviews inside same parent view based on their layer position!
In the spirit of being less rude.
func bringSubviewToFront(view: UIView) {
let superview = view.superview
superview?.addSubview(view)
}
That will bring it to the front. As in:
bringSubviewToFront(mySubview)
What the above code does is detach the view from wherever it is in its superview's hierarchy and reattach it to the top of all the subviews. This has the effect of bringing it to the front like you want. If the view isn't part of a hierarchy, then the function does nothing.

Storyboard UIView components hierarchy meaning?

What is the effect of having a UIView act as a child of another UIView in the scoreboard?
Using AVCam as an example, in the storyboard of the project, the components are layered out as following:
Observe that the 3 Button components act as children of “Cam Preview View”.
I’ve made an experiment and managed to get them to be children of “View”. This does not break any UIButton outlet functionality that I’ve managed to notice.
This is a design time choice by the developer. This changes how the controls can be moved by the constraints or other layout controls like springs and strut). Moving them around will not break any wired outlets however can introduce logical errors.
That said it's possible that there is no significant effect for this demo code.
In the first image you posted, those buttons are added as subviews of the Cam Preview View. It is the same as saying
[camPreviewView addSubview:button];
In the second image instead of the buttons subviews of the Cam Preview View, they are subviews of the View at the top of the hierarchy.
This is a design choice made by the developer. Clearly s/he wanted a view with three buttons contained inside as subviews. That way, you can move the Camera Preview View around and the buttons stay in their relative locations within the view.

Positioning items in overlapping UIViews in xib file

Let's say that I have a xib with a stack of UIViews on top of each other:
The bottom UIView(A) with a UIButton on it and when the button is pressed,
this layer is hidden and the next one is shown and put on top.
The next UIView(B) contains a clock counting down from 5 to 0
and when 0 is reached this UIView is hidden and the one described above is
moved to front and shown instead.
So just to make it more clear:
the composition of the xib:
A B
--Z direction-->
update: screenshot attached at the bottom of page.
So to my problem:
When (re)positioning the button or the clock using mouse in Xcode they tend to stick to the wrong
UIView. The more the Objects and "stacked" UIViews the greater the problem.
The Question:
Is there any way to, as with the layer "eye" in photoshop, isolate the UIViews and work on them one by one?
Observe!
I am aware that there are o there ways of achieving this swapping between view BUT this is not the issue. The real problem here is to actually position the button and the clock in the Xcode wysiwyg editor with the least hassle.
Observe!
-------- Added for clarification --------
Screenshot
I would like to isolate the views visually so when working on one of them, all the others are hidden and not open for interaction.
You can drag the second view (B) out of the main view hierarchy and place it below it (on the same level of the main view). That way you'll be able to edit each view separately.
Then you connect that view (B) to an outlet in your viewcontoller inorder to be able to add it to your main view during runtime...just set the frame and add it as a sub view.

iOS Overlay UI on Google maps

The bars at the top and bottom are made with ImageViews, the buttons and the logo are children of a view overlaid onto the mapView as seen here:
My specific problem is that the MapView is sucking away all touch events so no buttons are working. Ive solved it by enabling user interactions on the view that contains all my overlaid controls but it disables all interactions with the map. I have also tried to wrap the ui around a view that is not user interactable with two subviews (containing the bars) that are, which ends up in weird presentation errors and a lot of NSLog'd constraint errors.
Any ideas on how to properly achieve this layout? The map is not supposed to work if the user tries to interact with it by touching the grey-ish bars.
It looks like you have a single view that holds all of the overlay elements and it is above the Map View, therefore it will handle all touches and not your Map View.
Based on this design, what I would do is create a view that contains the top section and a view that contains the bottom section. Then, place those in their locations above the Map View, this will make it so that there is no view above the Map View in the middle.
Here you see, the green section is "Top Overlay" and the purple section is "Bottom Overlay", there is no view covering the mid section of the map view where you want your user to be able to interact with it.

Resources