ios - scroll and pinch in multiple UiScrollViews at the same time -
i have uicollectionview
4 custom cells. cell's delegate main view contains collectionview , extends custom cell delegate. each cell contains single uiscrollview
in turn contains , displays uiimageview
. now, can pinch , doubletap zoom in , out , move image inside cell's scrollviews.
i have in application "lock views" button should lock views together, if pinch (zoom or move) in cell, change should "copied" in other cells. 10% zoom increase in cell should trigger 10% zoom increase in others cells (independently each cell current zoomscale
). similarly, 10 unit movement left in 1 cell should move others cells 10 units left.
i'm using scrollviewdidscroll(_ scrollview: uiscrollview)
method detect change in scrollviews , call delegate in turn have access others cells in main uicollectionview
my first problem when used uiscrollview.zoom(to : rect)
or uiscrollview.zoomscale
trigger again scrollviewdidscroll(_ scrollview: uiscrollview)
in others cells creating king of infinite loop, managed fix using :
var iszooming = false func scrollviewcustomzoom(to rect: cgrect, animated : bool ) { iszooming = true scrollview.zoom(to: rect, animated: animated) iszooming = false }
and :
func scrollviewdidscroll(_ scrollview: uiscrollview) { if iszooming { return } // stuff, typically call delegate }
but problem : need calculate in scrollviewdidscroll
method, , need set in each cell in delegate in order have behavior i'm looking for?
i've tried play around scrollview.bounds
, scrollview.origin
or scrollview.size
, couldn't scaling factor behave properly.
any welcome , appreciated.
found solution own question. solution not call scrollviewdidscroll()
in others cells, wanted.
here trick :
// pinch-pan detection : func scrollviewdidscroll(_ scrollview: uiscrollview) { let neworigin = scrollview.bounds.origin let dx = neworigin.x - currentscrollvieworigin.x let dy = neworigin.y - currentscrollvieworigin.y let newscale = scrollview.zoomscale let ds = newscale - currentzoomscale if let d = delegate{ d.notifymouvementincell(self, dx: dx, dy: dy, ds: ds) } currentscrollvieworigin = scrollview.bounds.origin currentzoomscale = scrollview.zoomscale }
in delegate :
func notifymouvementincell(_ cell: customcell, dx: cgfloat, dy: cgfloat, ds: cgfloat){ if areviewslocked{ visiblecell in collectionview.visiblecells as! [imecasesmultidisplaycollectionviewcell]{ if visiblecell == cell { continue } visiblecell.copymouvementinforeigncell(horoffset: dx, vertoffset: dy, scaleoffset: ds) } } }
and in cells :
func copymouvementinforeigncell(horoffset dx: cgfloat, vertoffset dy: cgfloat, scaleoffset ds: cgfloat){ var neworigin = scrollview.bounds.origin neworigin.x += dx neworigin.y += dy scrollview.bounds.origin = neworigin var newscale = scrollview.zoomscale newscale += ds let affinetrans = cgaffinetransform(a: newscale, b: 0, c: 0, d: newscale, tx: 0, ty: 0) // imageview view contained in each of cell's scrollviews imageview.layer.setaffinetransform(affinetrans) currentzoomscale = scrollview.zoomscale currentscrollvieworigin = scrollview.bounds.origin }
hope someday !
Comments
Post a Comment