MKMapView on Storyboard on multiple Views with just 1 instance - ios

I got a MKMapView on a ViewController in Storyboard and set constraints for it. The thing is, that i want to use one single instance (which i created programatically) on multiple ViewControllers (it is the same ViewController multiple times --> on a PageViewController).
My question is if this is working or do i have to set the constraints for the mapView programatically. If so, i don't know how to set them properly in code for my MapView, could someone help there?
Need to give it a TopSpace to the last SubView and a BottomSpace to Container. Leading and Trailing Space set to 0.
Working with Swift.

i want to use one single instance (which i created programatically) on multiple ViewControllers (it is the same ViewController multiple times --> on a PageViewController).
You can't. The same instance of a UIView cannot appear in multiple superviews. This is basically for the same reason that you cannot be in two places at once.
Instead, as one view controller's view goes away, capture the center and span of its map view and pass that info along to the next view controller, so that its map view reproduces what the user was seeing previously.

Related

Multiple Variations of UI for the same view controller

I am working on an Exercise App, where UI depends on the type of Exercise. Some exercises have the question as text and answer as text. Some exercises have the question as text and answer as images. One more variation is image and text in question and image in the answer. I create a question object based on the values I get from API for a particular Exercise. That object has many fields as optional. For example, the image is optional. Now the challenge I am facing is what is the best way to handle such dynamic UI. In plain English, if it has the image, show the imageView and if it doesn't have the image, don't show the imageView and adjust other UI elements accordingly.
You can have one UIViewController subclass, and many different storyboards each with a different layout and subviews.
Each storyboard has the view controller's class set to your custom class in the identity inspector.
Your view controller has outlets for all possible subviews, and each storyboard connects its subviews to the outlets that are relevant to it.
When you need to present a particular variation of the string, you instantiate your view controller from a case-specific storyboard (programmatically or using segues and storyboard references).
If you only need to disable one particular subview in one case, you can do one of the following:
Set that subview's isHidden property to false. It will stay in place, and occupy the same area, but invisible.
Remove it from the main view by calling removeFromSuperview(). Be careful if other, remaining subviews rely on constraints against the removed subview for their layout, though.

Multiple instances of the same UIView in UIScrollView

I've used this answer to implement a UIScrollView with paging.
It works great as a start, but what I want to be able to do is for each page in the UIScrollView, I want a separate instance of the same UIView.
For example, say I have ContentViewController, and I want to use 4 instances of it's UIView;
1 for each of the pages on the UIScrollView - how do I go about doing that?
My initial thought was to instantiateViewController(withIdentifier), and then reuse it's .view' property inside thefor` loop, but this only gave me the correct view once, and the other 3 were blank subviews.
Any help would be much appreciated.
Thanks!
You could instantiate the ViewController multiple times (in a for loop) and then fetch each controller's view and add it to the scroll view. But you have to be aware that now you also have 4 Controllers, each for one view.

Creating a UIView to be displayed in multiple UIViewControllers

I am creating a simple little popup view, similar to the popup that appears when you push the volume buttons. I would like to display an instance of that popup view in different view controllers. I have been pondering a couple approaches, but I would like to know what is the best approach, taking into account MVC, complexity, and otherwise 'good' practices.
Currently, I am creating and displaying this UIView from within my UIViewController. I justified that approach since it's really a small view and I do a lot of work with it to modify its behavior in that VC, so that code was already going to be in the VC. Essentially, I make a frame, set the background, apply corner radius, add text to it, apply motion effects, then make it fade in then later fade out. I could copy and paste the code into my other VCs but that's obviously a bad approach.
I could create a subclass of UIView and I'm sure I could use drawRect to draw it, but I'm not sure exactly how to add that view to the VC exactly in the middle, unless I drag out a view to my VCs and change its class. But if I do that I can do most everything in Interface Builder anyways, which would be preferred especially if I can use Auto Layout to always keep it centered. But, I'd need to copy and paste that UIView into each VC and hide it - that doesn't sound good.
I could create a subclass of UIView and instead of drawing with drawRect, implement a method that creates the UIView and returns it. Then in the VCs I just call that method and add the view it returns as a subview. I've never done this, and I'm not sure if that's an appropriate approach.
What is a plausible approach to implementing such a view that can be thrown on screen from any of my VCs? Thanks!
Note that this view should always be the same size, in the center of the screen, not tied to any specific VC. It should remain on screen unaffected by transitions and such. It closely mimics the Volume popup.
I would like to display that same popup in multiple view controllers.
I expect that you mean you'd like to have separate instances of that same class in multiple view controllers. A given view can have only one superview, so it can't exist in more than one view at a time.
I'm not sure exactly how to add that view to the VC exactly in the middle
It's easy to center a view in its superview. To center horizontally, subtract the width of the view from the width of the parent. Divide the result by 2. That's your X coordinate. Same goes for the Y coordinate, except that you'd obviously use the heights.
An even easier method is to create a point by dividing the superview's width and height each by 2. Set your view's center property to that point.
What is a plausible approach to implementing such a view that can be thrown on screen from any of my VCs?
Don't try to reuse the same view. There's no need for that, and trying to pass it around between controllers will really complicate your code. Just have any controller that needs to display your popup create its own copy.
Remember, views are the interface to the data that's stored in your model -- they can display that data or let you interact with the model, but they shouldn't store app state themselves. Given that, there's no reason that you'd need to use the very same view in more than one view controller. As long as your pop up gets its data from the right place, you can have as many instances of it as you like.
If your popup really is separate from the content of any of your view controllers, another possible strategy is to use view controller containment. You can create one view controller that handles just the "app-wide" stuff, like this popup, and have it load and unload the various other view controllers as it's children. I'd caution against trying this, though -- it's probably more complicated than you need and surely more complicated than you should attempt right now given that you seem to still be getting your sea legs.
It sounds like MBProgressHUD is what you're looking for. FFCircularProgressView might also help.

Main view is moved on returning to ViewController from next one?

I have a view controller with multiple UIViews on it, made in two different ways, all sitting in a scrollview. The top one was added through storyboard, and was done so to make it easier to style and work with segues. The others are more of a newsfeed post type deal, and are dynamic, so they are programmatically added. When I travel to another ViewController from this one, and I'm not scrolled all the way to the top I find that when I return, my storyboard added view is moved up, and almost out of the screen.
How do I fix this? I feel like it has something to do with the scrollView or the fact that it was added in storyboard, since the other views dont move, just this one.

Can a view be added to multiple other views safely, if so what does removeFromSuperView: do in that case?

I am wondering what happens if a single instance of a UIView object gets added as a subview of multiple other views simultaneously.
If UIView:removeFromSubview: gets called then does it get removed from all superviews or just the currently displayed one?
For background:
I have a status-bar like view object that needs to be displayed within several different other views (each other view is managed by its own view controller).
[i.e. a) the user is in one view, b) something happens to make the status-bar-like view appear, c) the user switches to another view d)the status bar is still visible in the new view e) the status bar expires after a time and disappears from site. And so on]
Initially I implemented this by adding/removing it as required as a subview of the window, and this was managed by a singleton.
However due to some complications with some animations I have instead added it as a subview of each of the main view's for each of the view controllers.
Note that there are not multiple copies
When the view needs to be removed I am calling its removeFromSuperview:, and everything is all working perfectly.
However I am wondering what the situation is regarding the removal of the view, is it being fully removed or is there something else I need to do?
For example the view might get added to N view controller's views by calling addSubview as required (it will only get added to each view controller if that view controller actually launches)
However when it is being removed I am only calling removeFromSuperview: for the view of currently loaded view controller, not all view controllers it might have been added to.
Next time I navigate to one of these other view controllers it displays fine without the view being there, even though I didn't explicitly call removeFromSuperView.
As I said everything is working as it is, however at the back of my mind I feel there might be something missing?
Hope this was understandable.
You can only have it added to one view. Documentation is your friend!
(void)addSubview:(UIView *)view:
Views can have only one superview. If view already has a superview and that view is not the receiver, this method removes the previous superview before making the receiver its new superview.
From my point of view, having to add a same view to different parent views (and more important, from different view controllers) is an indication that something is wrong on the design...
However, if you really (really) need so, I had always thought that a view instance could have one and only one parent view... Moreover, you can access it by [myView superview] message, which gives you a UIView instance instead of an array... It may auto remove from its old parent before adding to a new superview?
About the design, what about creating it each time you need a new one and have a singleton to manage their status/logic?
Good luck with that!

Resources