Use NS[UI]ScrollView to manipulate projection - ios

I have a simple metal setup which draw image in the middle of MTKView. I wish I could add pinch zoom and other functionality as we have in scroll views, so i can zoom image and move it around with some thresholds.
I also don't want to implement it myself since my app will live in both Mac OS and iOS and this is twice more code to support and write.
Is there a way I could use default scroll view controlls to manipulate my projection? I mean set scroll view somehow on top of my view and get some data in delegate manner or whatever.
Any help would be appreciated!

You may want to try Metal2DScrollable sample code. The idea is that:
place MTKView behind (not a subview) UIScrollView,
Place dummy content view as a subview of UIScrollView
Make the dummy content view to be the target of zooming
Set up UIScrollView properly such as contentSize, contentInset etc.
Make both UIScrollView and dummy content view to be transparent
Calculate transform from dummy content view's bounds -> MTKView's coordinate -> device coordinate
Apply that transform when rendering with Metal
So, MTKView is not in the UIScrollView, but this tricks fools user's eyes.
https://github.com/codelynx/Metal2DScrollable
The same technique may work with macOS with some tweaks, but I haven't tried.

Related

Swift: Zooming image with scrollView like Facebook

I am trying to build an iOS app that will have the structure of Facebook's feed:
A vertical collection view that will have cells. Each cell will consist of image and text.
In fact, I am building my app with the help of this video by LetsBuildThatApp (this guy rocks by the way).
Currently, I am able to touch the image and animate it to full width, and also pan to dismiss it if velocity on Y-axis is more than a specific threshold.
What I want to achieve after that is to also be able to pinch/double tap to zoom. Like this:
I searched around and found some great articles on how to use UISCrollView to zoom. [Article1, Article2].
The problem is that I use autolayout to perform animations but these articles either use Storyboards or frames to position the image in the center of the scroll view [or at least this is how I understand it]. And also they don't involve any animations to start with.
Also, I don't want to present or push a view controller onto the navigation controller stack. I would rather animate the view on top of the base view as I do now.
Any idea on how to achieve this?
Thank you in advance!

How to render non-zoomed overlay over image in UIScrollView

My plan is to render a custom waveform inside an UIScrollView (to allow user to pan and scroll through the waveform). But additionally I want to render additional non-zoomed information on top of the waveform (like play position marker, time, ...)
So I have a static UIImage that is the pre-rendered waveform, and some small bits that i have to render on top of it dynamically (I don't want the position marker or text to bee zoomed on the waveform).
I have read that UIImageView is the most efficient way to render a simple image (Most efficient way to draw part of an image in iOS), but that is not sufficient for me because i have to render something on top of it. Or is this somehow possible?
I dont see a way to use the UIScrollView for now, because it zooms everything inside right? But as mentioned, I need only the image zoomed, but the additional data non-zoomed.
Can I implement this using UIScrollView? Or do I have to implement a custom view that takes care of zooming and panning by itself?
If I understood your properly, you need to zoom one view(UIImageView) and prevent zooming another view (UILabel, for instance). So, you are wrong that Scroll View zoom everything inside it. UIScrollViewDelegate has method
optional func viewForZoomingInScrollView(_ scrollView: UIScrollView) -> UIView?
It should return view that should be zoomed. Hope, I helped you.

Drawing a graph within a UIScrollView

I am exploring the idea of drawing some custom primitives (using CGContext) on a view that is scrollable and larger than the phone screen width.
The idea would be to use the "power" of a UIScrollView by programmatically scrolling the content of the view as the content is added and decouple in this way the scrolling handling (and general UI interaction with the view) from the content drawing.
Is this a feasible approach in iOS?
Yes it is. The easiest approach AFAIK would be to add a UIView onto the UIScrollView. You would then draw on that UIView instance - after drawing another part of your graph/image you would need to inform the containing scroll view, via a delegate for example, that it needs to update its contentSize. This would of course be the size of the UIView upon which you drew. The update is needed, beacuse it seems that you may need to increase your drawing area size as you do it.

How to zoom on UIView

In my iOS app I want my users to be able to zoom in on the screen. My main uiview contains several subviews which contain images. I want my uipinchgesturerecognizer to either change the scale, or ideally use some "zoom" rather than scaling each subview.
Please and thank you.
This can be accomplished with UIScrollView. First create a scroll view as the base of your view hierarchy, putting your previous container view as a subview of the scroll view. Set the delegate of the scroll view to self and implement the delegate method viewForZoomingInScrollView, in which you should return the view that will be zoomed in (your original container view). This will allow the user to pinch and zoom your original UIView.
It's hard to provide advice on this without having a clearer view of what exactly you want to achieve.
Can you include a link to a sketch? For example, do you want the individual subviews to remain the same size but the layout to change ? Do you want the individual subviews to resize but their contents to be upscaled?
If you simple want to treat the subview as (basically) a single image which just happens to have other images in it, then maybe it would be better to render it as one and then scale that?

Fade UIImageView as it approaches the edges of a UIScrollView

I have a UIScrollView over an image at the bottom of my app that acts as a dock with icons that can be scrolled through horizontally. Instead of the harsh edges of the UIScrollView, I would like the icons to fade out for a more aesthetically pleasing look. Being new to iOS development, I don't know if either of these would be valid options:
Create a faded image to use as an overlay on the scrollview so the
icons only appear through the visible portion.
Actually change the
alpha of the images based on their distance from the center (or from
each edge).
I suspect the first idea would be the most simple, but I'd like to throw this out there for any other ideas.
Note: I did see this tutorial, however that technique assumes that the background is a solid color. If I were to do it programatically, I would probably need to fade the individual images.
You can definitely implement something along the lines of #2. It'd be something similar to what the tutorial describes. The alpha transition however won't be as smooth as using the gradient layer mentioned in the tutorial or using an image since the entire icon would have the same alpha. How much discernible the difference is depends on the size of your icons. Smaller icons, very few will be able to tell the difference. Larger icons the difference would be quite clear.
You'd have to implement the
(void)scrollViewDidScroll:(UIScrollView *)scrollView
method in your scroll view's delegate class. This method will get called every time the scroll view changes the location of its content. In this method you can call its subviews and adjust their alphas as required. To optimize it a bit instead of calling the alpha adjustments on all the elements you can just update the subviews which are still partially/completely visible.
EDIT: to figure out which views to adjust you'll use the contentOffset property of the scrollView that gets passed as a parameter in the above method.

Resources