Reputation: 481
New guy here to programming. Also, my first post. I did try to do some research over this, and I did find some threads, but most were a few years old or not for iOS.
In an iOS app I am trying to place clickable buttons over a high definition image of a mechanical panel of some equipment. The idea is the user could zoom into the image, tap over i.e. switch, and get a pop up that explains what the switch is for.
After watching some videos I was able to create a UIScrollView and place a UIImageView of the HD image into it. I can zoom in/out and move the panel fine.
I figured using UIButton to define "clickable" areas of the panel would be one way to go (not sure if this is the best approach). However, the buttons are giving me some problems:
After zooming in, the buttons won't stay over the same pixels relative to the HD image, and the button's size does not "grow" with zooming. So when zoomed in, the area the button covers is smaller and it is not over the correct place.
I have tried to apply constrains relative to the HD image, and also relative the scroll view. I have tried to put the image and the button into a stack. Obviously, I am missing some basics here. It seems this is a bit too advanced for where I am at.
Any ides on how to fix this? Also, would it be better to try going for tap gestures instead of UIButtons?
Thank you for your time! PS: Any tutorial videos or articles about this topic would be appreciated.
Upvotes: 1
Views: 713
Reputation: 481
I finally have found the answer. It is very simple. The button needs to be added as a subview of the imageView where the image resides. I was not able to do this through the interface, only programmatically like this:
imageView.addSubview(button)
It seems, Swift takes care of the rest. The button is moving and scaling perfectly with the image.
Upvotes: 1
Reputation: 62676
One idea is to make the button a child of the scroll view's parent (a sibling to the scroll view), ordered after the scroll view so it sits on top.
parent view (probably the view controllers view)
|
|-----------|
scrollView button
Let's say, before the scroll has been scrolled or zoomed, you'd like the button to appear at CGRect imageButtonFrame = CGRectMake(10,20,80,40)
. We might say these coordinates are in "image space". The function that maps these to the scroll view's sibling looks like this:
UIView *parentView = self.view; // this assumes both button and scrollView are children of the view controller's view
self.button.frame = [scrollView convertRect:imageButtonFrame toView:parentView];
What's nice about this is that the UIScrollView, aware of it's own contentOffset
and zoomScale
, does the computation with respect to those values. As long as you use that code snippet to set the button's frame, that frame will remain fixed in image space as imageButtonFrame.
Keep the frame up-to-date by becoming the delegate of the scrollView...
self.scrollView.delegate = self;
And find out when the offset or zoom level changes with:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
self.button.frame = // ... as above
}
Same for scrollViewDidZoom:(UIScrollView *)scrollView
Upvotes: 0