ios - How to make UIScrollView zoom in only one direction when using auto layout -
i'm attempting make uiscrollview allow zooming in horizontal direction. scroll view setup pure autolayout approach. usual approach suggested in number of stack overflow answers (e.g. this one) , other resources. have used in apps before autolayout existed. approach follows: in scroll view's content view, override settransform()
, , modify passed in transform on scale in x direction:
override var transform: cgaffinetransform { { return super.transform } set { var t = newvalue t.d = 1.0 super.transform = t } }
i reset scroll view's content offset doesn't scroll vertically during zoom:
func scrollviewdidzoom(scrollview: uiscrollview) { scrollview.contentsize = cgsize(width: scrollview.contentsize.width, height: scrollview.frame.height) scrollview.contentoffset = cgpoint(x: scrollview.contentoffset.x, y: 0.0) }
this works nicely when not using autolayout:
however, when using autolayout, content offset ends wrong during zooming. while content view scales in horizontal direction, moves vertically:
i've put example project on github (used make videos in question). contains 2 storyboards, main.storyboard, , noautolayout.storyboard, identical except main.storyboard has autolayout turned on while noautolayout not. switch between them changing main interface project setting , can see behavior in both cases.
i'd rather not switch off autolayout solves number of problems implementing ui in nicer way required manual layout. there way keep vertical content offset correct (that is, zero) during zooming autolayout?
edit: i've added third storyboard, autolayoutvariablecolumns.storyboard, sample project. adds text field change number of columns in gridview, changes intrinsic content size. more closely shows behavior need in real app prompted question.
think figured out. need apply translation in transform offset centering uiscrollview tries while zooming.
add gridview:
var unzoomedviewheight: cgfloat? override func layoutsubviews() { super.layoutsubviews() unzoomedviewheight = frame.size.height } override var transform: cgaffinetransform { { 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 transform, need know unzoomed height of view. here, i'm grabbing frame size during layoutsubviews() , assuming contains unzoomed height. there edge cases that's not correct; might better place in view update cycle calculate height, basic idea.
Comments
Post a Comment