How to implement custom UIView which is scrollable/zoomable? - ios

I want to create a "timeline" view. I'm comfortable with the GraphicsContext drawing API and using it in the drawRect: method. What I'm unclear of is the right/idiomatic way to make this view be scrollable/zoomable.
Is it more common to a) subclass UIScrollView or b) embed my custom view in stock UIScrollView placed inside storyboard?
Depending on which I use, how do I communicate my "desired bounds" to the scrolling machinery? And how do I make my drawing code aware of what the current scale/scroll is so I can draw appropriately.
(I did google for this, and haven't found any recent and simple recipes for this)

Don't subclass or embed. Set a UIScrollView as the outlet of your viewcontroller. UIScrollView inherits from UIView so you can treat it just like the normal UIView outlet of your view controller, plus you can scroll it.

Related

How to resize custom (created in separate file) UIView height on the ViewController which uses it?

I have a custom UIView (consisting of .swift and .xib files). There is a button inside of it which changes its height.
I'm using this custom UIView some of my ViewController. To do it I drag UIView on the ViewController and set its class to my custom UIView. This also allows me to use this button and "change" displayed size of my custom UIView.
However the size of UIView which contains my custom UIView doesn't change and I cannot use GMSMapView which lies under this view.
How can I solve this issue and change actual height of this view in the ViewController too?
The easiest way is to create an outlet of a constraint from storyboard and adjust its constant-property. That will course the view to resize.
Its an unusual behavior that a view resizes itself. The SuperView or ViewController should manage things like that.
When creating an outlet of the constraint, you should consider creating the outlet within the ViewController and not within the view.

Custom view inside scroll view inside table cell is not responding to events

I have a UITableView in my view controller, and inside the cell there's a horizontal UIScrollView and inside this scroll view, I created many instances of a custom UIView (loaded from NIB file)
UITableViewCell
-- UIScrollView
-- MyView: UIView
Now MyView is not detecting touches, userInteractionEnabled is set to YES on every view in the hierarchy and I tried both ways
Implement touchesEnded: in MyView
Add a UITapGestureRecognizer to it
Both ways don't work, I guess it's something related to the fact that I have a UIScrollView inside the UITableViewCell
I am writing the application in Swift, not Objective-C, I don't think it matters since I guess it's a UIKit issue but who knows.
If you have any hint, I am all ears.
Thank you
Alternative for this case is add UITableViewCustomCell and add UICollectionView with horizontal scroll in Custom cell . It is more optimized way than adding UIView in scroll view because you can greatly speed things up. Instead of instantiating a lot of cells, you just instantiate as many as needed, i.e. as many that are visible (this is handled automatically). If scrolling to an area in the list where there are "cells" that haven't got their visual representation yet, instead of instantiating new ones, you reuse already existing ones.

Objective-c ViewControllers and Views

I know this has been talked about ad nauseam on here but I'd like to get some perspective from other developers:
If I have a view controller with a view and then I add subviews to that view, does each subview need its' own viewcontroller or can the first viewcontroller also control the subviews?
So
UIViewController
UIView
UIView
UIButton
UILabel
UIView
...
the subviews do not take up the whole screen - they are for the most part the width of the screen but maybe 200.0f tall or less. They display information for a sales tool app.
The rule of thumb I was presented when I first started iOS development was if the view took up the whole screen, then it required its own viewcontroller, if not make it the subview of a viewcontrollers.view
Just wondering what the accepted approach is.
The View controller can access the views that are created in XIB, just create IBOutlet properties for the views in view controller source files and link the views to file's owner in interface builder.
Your rule of thumb is correct.

How would I create an "About" page like this for my app? How do I have a UITableView (grouped) under a UIView?

Take this about page for Things:
I'm having trouble creating something similar. I just want a UITableView under a UIView with a UIImageView and a UILabel in it.
If I use a UIViewController and so I can position the UITableView downward, I get this error: "Static table views are only valid when embedded in UITableViewController instances."
If I use a UITableViewController with a grouped style and use contentInset on self.tableView to move it down ([self.tableView setContentInset:UIEdgeInsetsMake(150,0,0,0)];) I can't figure out how to place a view above it. If I try to attach anything to self.view it crashes (obviously). Same happens if I attach anything to self.tableView.
I then tried making the UIView the header of my UITableView section (I only need one section) but I can't get it to move up enough. It just sits inside the UITableView almost.
How do I have a UITableView (grouped style) exist with a UIView above it?
This can be achieved easily using the tableHeaderView property of UITableView. If you are using Interface Builder (which it looks like you are), then you can just drag a UIView above the table view and it will be set as the table's header view. All you need is a UITableViewController; no need for UIViewController and manually laying it out.
That's because the view probably isn't placed on top of the table but rather within the table's section 0 header. Or, even more likely, the view in question is just a regular UITableViewCell with a 0 alpha background.
Either of these options would allow the top view to be scrolled out of frame as the user scrolls under every condition.
I recommend [MDAboutController] (https://github.com/mochidev/MDAboutController)
It's easy to integrate and you don't have to waste any time configuring the UITableView.

iOS prevent subview of tableview from scrolling with tableview

I have added a subview to my tableview and when ever the user scrolls the tableview, the subview scrolls with it. How do I prevent this? I know it's probably along the lines of not adding the view to the tableview's subviews, but I have no knowledge of any other ways to do this. Thanks.
If you want to make a view a subview of the table view, then you can make it floating (non-scrolling) by changing its origin.y value in the scrollViewDidScroll method.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
self.iv.frame = CGRectMake(self.ivOrigin.x, self.ivOrigin.y + self.tableView.bounds.origin.y, self.iv.frame.size.width, self.iv.frame.size.height);
}
In this example, "iv" is a property for an image view, and "ivOrigin" is a property for the initial origin of the image view (defined when I created the image view and its frame in viewDidLoad).
The UITableView is built and intended to be a view of things that scroll.
So, you can either fight that, which as you're discovering is quite hard since everything about the component is built and focused around scrolling and fast display of a subset of the full list data... Or, you can not fight it and put your static item on top of the table as a fixed-position item.
If there's a reason you can't add the table view and your animate-out item in your main view, you can always add a custom UIView class that contains both the table view and your animated view. Have your custom view class expose the contained table view as a .table property, and the container you're putting things in can be tweaked to use "mycontainerObject.tableview" instead of just "tableview" where needed.
Yes, it's a little more work to write the custom UIView subclass and give it a couple properties to hold the UITableView and whatever UIView you're animating out.. but it's likely a lot safer in the long run than trying to "hack" into the UITableView's methods and view hierarchy to try to give it a "fixed in place" behavior.

Resources