How to make UIScrollView zoom in only one direction when using auto layout
Think I figured it out. You need to apply a translation in the transform to offset the centering UIScrollView tries to do while zooming.
Add this to your GridView:
var unzoomedViewHeight: CGFloat?
override func layoutSubviews() {
super.layoutSubviews()
unzoomedViewHeight = frame.size.height
}
override var transform: CGAffineTransform {
get { return super.transform }
set {
if let unzoomedViewHeight = unzoomedViewHeight {
var t = newValue
t.d = 1.0
t.ty = (1.0 - t.a) * unzoomedViewHeight/2
super.transform = t
}
}
}
To compute the transform, we need to know the unzoomed height of the view. Here, I'm just grabbing the frame size during layoutSubviews() and assuming it contains the unzoomed height. There are probably some edge cases where that's not correct; might be a better place in the view update cycle to calculate the height, but this is the basic idea.
Zoom only horizontally UIView in UIScrollView
I have figure out a temporary solution thank you to LaurentMaquet. At some point I will post the final soundWaveView as it is in development at the moment.
The changes made are:
1- Create a custom class for soundWave.
class WaveView:UIView{
var unzoomedViewHeight: CGFloat = 0
override var transform: CGAffineTransform{
get{ return super.transform }
set{
var t = newValue
t.d = 1.0
t.ty = (1.0 - t.a) * unzoomedViewHeight/2
super.transform = t
}
}
override func layoutSubviews() {
super.layoutSubviews()
unzoomedViewHeight = frame.size.height
print("\(logClassName) did layout to \(AppHelper.traitStatus) -> frame = \(frame)")
}
}
2- Make my soundView var be a SoundView
private (set) lazy var waveView:WaveView = {
let rtView = WaveView()
rtView.translatesAutoresizingMaskIntoConstraints = false
rtView.backgroundColor = .clear
rtView.addGestureRecognizer(UITapGestureRecognizer(target: self,
action: #selector(waveViewDidTouch)))
return rtView
}()
Result
UIView. How do I constrain scaling to one dimension only
Similar to what I describe in this answer, you can create a UIView subclass and override the -setTransform: accessor method to adjust the transform that the UIScrollView will try to apply to your UIView. Set this UIView to host your content subviews and make it the subview of the UIScrollView.
Within your overridden -setTransform:, you'll need to take in the transform that the UIScrollView would like to apply and adjust it so that the scaling only takes effect in one direction. From the documentation on how CGAffineTransform matrices are constructed, I believe the following implementation should constrain your scaling to be just along the horizontal direction:
- (void)setTransform:(CGAffineTransform)newValue;
{
CGAffineTransform constrainedTransform = CGAffineTransformIdentity;
constrainedTransform.a = newValue.a;
[super setTransform:constrainedTransform];
}
Zooming out from content of UIscrollview
I am not sure if this will help you, but this method works for me when zooming in iOS 8. In this code, an imageView is in the scroll view.
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView.minimumZoomScale = 0.5;
self.scrollView.maximumZoomScale = 6.0;
self.scrollView.contentSize = self.PhotoView.frame.size;
self.scrollView.delegate = self;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.PhotoView;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView*)view atScale:(CGFloat)scale{
}
UIScrollView with Horizontal Zoom - Bezier Paths Drawn within Subviews Are Blurry
My initial thought, having not done this before exactly, is to store the graph as a bezier path rather than as a set of view line and point views, and based on a single unit axis. You could convert your data into this form just for drawing.
So, all points on the bezier path are normalised into the range 0 to 1.
Once you've done that you can apply a transform to the bezier path to translate (move) and scale (zoom) to the part you want and then draw the bezier path at full resolution.
This will work and is different to your current situation because your current code draws the views and then scales then so you get artifacts. The above option scales the path and then draws it.
Can a UIScrollView be adapted to zoom horizontally but not vertically? (how)
Assuming you don't actually want to stretch/shrink the button text, the easiest way is to resize all the buttons. I know, it's a pain.
UIScrollView: zoom scale for each dimension/axis
I guess in your case you're better off not using a UIScrollView
, and instead setting up a UIPinchGestureRecognizer
yourself on the views you want to transform.
The GestureRecognizer would track the fingers and decide whether (and how much) to scale in which dimension. Based on this, you can set your view's transform
property. As an example, a transformation matrix that doubles the width but leaves height intact would be CGAffineTransformMakeScale(2.0, 1.0)
.
To leverage UIScrollView's scrolling, you then embed your view into a UIScrollView, and set the contentSize
and contentOffset
properties accordingly from your GestureRecognizer's callback methods.
Related Topics
How to Get Account Name from Contact Framework
Uitextfield Starting Cursor Position Is Wrong
Ios11 Uibarbuttonitem Not Working
iOS Sharecontext Tapping on Suggestion Intent Property of Extensioncontext Is Nil
Which Passes How to Access in Apple Wallet
App Installation Failed: Unknown Error Xcode 7
Get "No Keychain Available" Error When Try to Access Keychain from App Extension
How to Send Emails in Swift Using Mailgun
Pure Swiftui Login, Signup, Register Flow, Is It Possible
Ambiguous Use of Registerclass with Swift
How to Make Playground Execution Time Is as Fast as If We Run in iOS Application
Ios-Charts How to Put Uiimage Beside a Point
How to Add the Same Background Image to All Views in My iOS App Using Swift