问题
I using CGAffineTransformMakeRotation for the Rotation of an Image and CGAffineTransformMakeTranslation for the Translation of an Image. This is my code:
-(void)rotateTranslate
{
r++;
CGAffineTransform transform = CGAffineTransformMakeRotation(r);
imageView.transform = transform;
x++;
y++;
CGAffineTransform transform1=CGAffineTransformMakeTranslation(x,y);
imageView.transform= transform1;
[self performSelector:@selector(rotateTranslate) withObject:self afterDelay:0.2];
}
My Problem is the Image is only Translating it is not Rotating. If I use the Rotate and Translate separately means it works Pretty well. How can I modify my code to work both well?
回答1:
The problem is that you are making an individual rotation and then translation and setting it. So the rotation is overridden by the translation. You must do something like this,
CGAffineTransform transform = CGAffineTransformRotate(imageView.transform, 1);
transform = CGAffineTransformTranslate(transform, 1, 1);
imageView.transform= transform;
[self performSelector:@selector(rotateTranslate) withObject:self afterDelay:0.2];
But this will not animate the rotation. It will just jump from the current transform to the end transform.
And you don't seem to have an end point defined.
回答2:
Here is my code, I didn't have time to filter out the code, but it includes all the feature like rotate, translate and scale the image in scrollview.
import UIKit
import AudioToolbox import PureLayout
let MIN_ZOOM_SCALE:CGFloat = 1 let MAX_ZOOM_SCALE:CGFloat = 5 let DEFAULT_ZOOM_SCALE:CGFloat = 2
let markerSize:CGFloat = GET_PROPORTIONAL_HEIGHT(height: 50)
class ViewController: UIViewController, UIScrollViewDelegate, AGConfiguratorDelegate, UITableViewDataSource, UITableViewDelegate{
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var btnTest: UIButton!
@IBOutlet weak var btnTest1: UIButton!
@IBOutlet weak var btnTest2: UIButton!
var markerCount:Int = 0
var arrPlacedMarkers = [UIButton]()
var isPullViewOpened:Bool = false
var table:UITableView!
var viewHeader:UIView!
var viewBtnContainer:UIView!
var timerRotateButtons:Timer!
var btnRotateLeft:UIButton!
var btnRotateRight:UIButton!
var selectedBtnMarker:UIButton?
var maxYTouchPointToScrollUp:CGFloat = -1
let configurator = AGPullViewConfigurator()
//MARK:- VIEW
override func viewDidLoad() {
super.viewDidLoad()
self.doSetupUI()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
// var xx = SCREEN_WIDTH * 257.076682316119 / self.imageView.image!.size.width // var yy = SCREEN_HEIGHT * 599.097704011388 / self.imageView.image!.size.height
// var xx = SCREEN_WIDTH * 395.150738305702 / self.imageView.image!.size.width // var yy = SCREEN_HEIGHT * 295.700957624736 / self.imageView.image!.size.height
var xx = SCREEN_WIDTH * 253.0 / self.imageView.image!.size.width
var yy = SCREEN_HEIGHT * 591.549295774648 / self.imageView.image!.size.height
print("xx : \(xx) yy : \(yy) ")
xx = xx + (markerSize/2)
yy = yy + (markerSize/2)
print("xx : \(xx) yy : \(yy) ")
self.addButtonWithAtPoint(touchedPoint: CGPoint(x: xx, y: yy))
print("\nMAP : \(self.imageView.image!.size)")
print("SCR : \(self.scrollView.frame)")
print("VIE : \(self.view.frame)")
}
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
}
//For correct working of layout in early versions of iOS 10
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.configurator.layoutPullView()
let pullViewHeight = self.configurator.contentView.superview?.frame.size.height
self.maxYTouchPointToScrollUp = (SCREEN_HEIGHT - (pullViewHeight)! - scrollView.frame.origin.y)
}
//MARK:- SAVE MARKER IN DEFAULTS
func saveMarkerInDefault(){
var counter:Int = 0
for eachButton in arrPlacedMarkers{
print(" \(counter) x : \(eachButton.frame.origin.x) y : \(eachButton.frame.origin.y)")
if(counter == 0){
let xPos = eachButton.frame.origin.x
let yPos = eachButton.frame.origin.y
let newXPos = (imageView.image!.size.width * xPos) / SCREEN_WIDTH
let newYPos = (imageView.image!.size.height * yPos) / SCREEN_HEIGHT
print("default stored x : \(newXPos) y : \(newYPos)")
UserDefaults.standard.set(newXPos, forKey: "xPos")
UserDefaults.standard.set(newYPos, forKey: "yPos")
}
counter += 1
}
}
func getMarkerFromDefaults() -> [AIMarker]{
var arrSavedMarker = [AIMarker]()
if let xPos = UserDefaults.standard.object(forKey: "xPos") as? CGFloat{
if let yPos = UserDefaults.standard.object(forKey: "yPos") as? CGFloat{
let marker = AIMarker(x: xPos, y: yPos)
arrSavedMarker.append(marker)
}
}
return arrSavedMarker
}
//MARK:- UI SETUP
func doSetupUI() {
btnTest.isHidden = true
btnTest1.isHidden = true
btnTest2.isHidden = true
// IMAGEVIEW
imageView.clipsToBounds = true
imageView.contentMode = UIViewContentMode.scaleToFill
imageView.isUserInteractionEnabled = true
imageView.image = UIImage(named: "RoomPlan2")
self.scrollView.applyBorderDefault()
// SCROLLVIEW
scrollView.minimumZoomScale = MIN_ZOOM_SCALE
scrollView.maximumZoomScale = MAX_ZOOM_SCALE
scrollView.zoomScale = DEFAULT_ZOOM_SCALE
scrollView.delegate = self
scrollView.bounces = false
scrollView.bouncesZoom = false
// SINGLE TAP
let singleTap = UITapGestureRecognizer(target: self, action: #selector(self.singleTapHandler(_ :)))
singleTap.numberOfTapsRequired = 1
singleTap.numberOfTouchesRequired = 1
imageView.addGestureRecognizer(singleTap)
// DOUBLE TAP
let doubleTap = UITapGestureRecognizer(target: self, action: #selector(self.doubleTapHandler(_ :)))
doubleTap.numberOfTapsRequired = 2
doubleTap.numberOfTouchesRequired = 1
imageView.addGestureRecognizer(doubleTap)
singleTap.require(toFail: doubleTap)
// LONG PRESS
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressHandlerForMapImageView(_:)))
imageView.addGestureRecognizer(longPressGesture)
self.doSetupRotateButtons()
self.doSetupPullView()
}
func doSetupRotateButtons(){
let btnSize:CGFloat = GET_PROPORTIONAL_HEIGHT(height: 30)
let viewBtnContainerTrailingSpace:CGFloat = GET_PROPORTIONAL_HEIGHT(height: 10)
let spaceBetweenBtns:CGFloat = GET_PROPORTIONAL_HEIGHT(height: 10)
// VIEW BTN CONTAINER
viewBtnContainer = UIView(forAutoLayout: ())
self.view.addSubview(viewBtnContainer)
viewBtnContainer.autoPinEdge(toSuperviewEdge: ALEdge.trailing, withInset: GET_PROPORTIONAL_HEIGHT(height: viewBtnContainerTrailingSpace))
// BTN ROTATE LEFT
btnRotateLeft = UIButton(type: .system)
viewBtnContainer.addSubview(btnRotateLeft)
btnRotateLeft.addTarget(self, action: #selector(self.btnRotateLeftHandler(sender:)), for: .touchUpInside)
btnRotateLeft.isExclusiveTouch = true
btnRotateLeft.setImage(UIImage(named: "rotate_left"), for: .normal)
btnRotateLeft.imageView?.contentMode = UIViewContentMode.scaleAspectFit
btnRotateLeft.autoSetDimensions(to: CGSize(width: btnSize, height: btnSize))
btnRotateLeft.autoPinEdgesToSuperviewEdges(with: UIEdgeInsetsMake(5, 5, 5, 5), excludingEdge: ALEdge.trailing)
// BTN ROTATE RIGHT
btnRotateRight = UIButton(type: .system)
viewBtnContainer.addSubview(btnRotateRight)
btnRotateRight.addTarget(self, action: #selector(self.btnRotateRightHandler(sender:)), for: .touchUpInside)
btnRotateRight.isExclusiveTouch = true
btnRotateRight.setImage(UIImage(named: "rotate_right"), for: .normal)
btnRotateRight.imageView?.contentMode = UIViewContentMode.scaleAspectFit
btnRotateRight.autoSetDimensions(to: CGSize(width: btnSize, height: btnSize))
btnRotateRight.autoPinEdgesToSuperviewEdges(with: UIEdgeInsetsMake(5, 5, 5, 5), excludingEdge: ALEdge.leading)
btnRotateRight.autoPinEdge(ALEdge.leading, to: ALEdge.trailing, of: btnRotateLeft, withOffset: spaceBetweenBtns)
btnRotateLeft.tag = 111
btnRotateRight.tag = 222
// ADDING LONG PRESS GESTURE
let longPressGestureRotateLeft = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressHandlerForRotateLeftButton(_:)))
btnRotateLeft.addGestureRecognizer(longPressGestureRotateLeft)
let longPressGestureRotateRight = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressHandlerForRotateRightButton(_:)))
btnRotateRight.addGestureRecognizer(longPressGestureRotateRight)
// viewBtnContainer.applyBorder(color: UIColor.red, width: 2) // btnRotateRight.applyBorderDefault() // btnRotateLeft.applyBorderDefault()
}
//MARK:- *********
func doSetupPullView(){
self.configurator.setupPullView(forSuperview: self.view, colorScheme: ColorSchemeTypeWhite)
// let pullViewHeight = self.configurator.contentView.superview?.frame.size.height // print("PULL VIEW HEIGHT : ((self.configurator.contentView.superview?.frame)!)") // print("IMG : (imageView.frame) SC : (scrollView.frame)") // print("SCREEN HEIGHT : (SCREEN_HEIGHT) XX : (SCREEN_HEIGHT - pullViewHeight! - scrollView.frame.origin.y)") // let maxBottomTapValue = (SCREEN_HEIGHT - pullViewHeight! - scrollView.frame.origin.y)
viewBtnContainer.autoPinEdge(toSuperviewEdge: ALEdge.bottom, withInset: (height: self.configurator.contentView.superview!.frame.size.height))
self.configurator.percentOfFilling = 90//85
self.configurator.delegate = self
self.configurator.needBounceEffect = true
self.configurator.animationDuration = 0.45
self.configurator.enableShowingWithTouch = true;
self.configurator.enableHidingWithTouch = true;
self.configurator.enableBlurEffect(withBlurStyle: .dark)
self.hidePullViewFromBottom(animated: false)
//Test UITableView
table = UITableView(frame: CGRect(), style: .plain)
table.dataSource = self
table.delegate = self
table.separatorStyle = .none;
table.backgroundColor = UIColor.clear
table.isUserInteractionEnabled = false
let viewFooter = UIView(frame: CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: GET_PROPORTIONAL_HEIGHT(height: 40)))
viewFooter.backgroundColor = UIColor.lightGray
let btnRemoveMarker = UIButton(forAutoLayout: ())
btnRemoveMarker.setTitle("Remove Marker", for: .normal)
btnRemoveMarker.addTarget(self, action: #selector(self.btnRemoveMarkerTapHandler(_:)), for: .touchUpInside)
viewFooter.addSubview(btnRemoveMarker)
btnRemoveMarker.autoCenterInSuperview()
table.tableFooterView = viewFooter
//Filling whole AGPullView with test UITableView
self.configurator.fullfillContentView(with: table)
self.configurator.blockBtnCloseHandler = {
if(self.isPullViewOpened){
self.configurator.hide(animated: true)
}else{
self.hidePullViewFromBottom(animated: true)
}
}
}
//MARK:- *********
//MARK:- SHOW / HIDE PULL VIEW
func showPullViewAtBottom(animated isAnimated:Bool){
let tempSuperView = self.configurator.contentView.superview
if(tempSuperView!.transform.isIdentity && tempSuperView?.isHidden == false){
// print("already opened") return } tempSuperView?.isHidden = false self.configurator.doShowTopBottomButtons() tempSuperView?.transform = CGAffineTransform.init(translationX: 0, y: tempSuperView!.height) UIView.animate(withDuration: 0.2, animations: { tempSuperView?.transform = CGAffineTransform.init(translationX: 0, y: 0) }) { (bbb) in }
showRotateButtons(withAnimation: isAnimated)
}
func hidePullViewFromBottom(animated isAnimated:Bool){
let tempSuperView = self.configurator.contentView.superview
if(tempSuperView!.transform.isIdentity && tempSuperView?.isHidden == true){
// print("already closed") return }
let duration:TimeInterval = isAnimated ? 0.2 : 0.0
UIView.animate(withDuration: duration, animations: {
tempSuperView?.transform = CGAffineTransform.init(translationX: 0, y: tempSuperView!.height)
}) { (bbb) in
tempSuperView?.transform = CGAffineTransform.init(translationX: 0, y: 0)
tempSuperView?.isHidden = true
self.configurator.doHideTopBottomButtons()
}
hideRotateButtons(withAnimation: isAnimated)
}
//MARK:- SHOW / HIDE ROTATE BUTTONS
func showRotateButtons(withAnimation animated:Bool){
if self.viewBtnContainer != nil{
UIView.animate(withDuration: animated ? 0.2 : 0.0, animations: {
self.viewBtnContainer.alpha = 1
}) { (bb) in
}
}
}
func hideRotateButtons(withAnimation animated:Bool){
if self.viewBtnContainer != nil{
UIView.animate(withDuration: animated ? 0.1 : 0.0, animations: {
self.viewBtnContainer.alpha = 0
}) { (bb) in
}
}
}
//MARK:- ADD BUTTON
func addButtonWithAtPoint(touchedPoint:CGPoint) {
print("\n\n\nTOUCH POINT : \(touchedPoint)")
// CREATING BUTTON FOR MARKER
let xPos = touchedPoint.x - (markerSize/2)
let yPos = touchedPoint.y - (markerSize/2)
let btnMarker = UIButton(type: .custom)
btnMarker.frame = CGRect(x: xPos, y: yPos, width: markerSize, height: markerSize)
print("xpos : \(xPos) ypos : \(yPos)----\(btnMarker.frame)")
print("ce----\(btnMarker.center)")
btnMarker.setTitleColor(UIColor.white, for: .normal)
btnMarker.setTitle("M\(markerCount + 1)", for: .normal)
btnMarker.tag = markerCount
btnMarker.titleLabel?.numberOfLines = 1
btnMarker.titleLabel?.adjustsFontSizeToFitWidth = true
btnMarker.titleLabel?.lineBreakMode = .byClipping
btnMarker.addTarget(self, action: #selector(self.btnMarkerTapHandler(_:)), for: .touchUpInside)
self.imageView.addSubview(btnMarker)
let imageArrow = UIImage(named: "arrow")
btnMarker.setImage(imageArrow, for: .normal)
// ADDING PAN GESTURE
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.panGestureHandler(_:)))
btnMarker.addGestureRecognizer(panGesture)
// ADDING ROTATION GESTURE
// let rotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(self.rotationGestureHandler(_:))) // btnMarker.addGestureRecognizer(rotateGesture)
// ADDING MARKER IN MAIN ARRAY
self.arrPlacedMarkers.append(btnMarker)
markerCount += 1
// SCALING MARKER AS PER MAP'S CURRENT ZOOM SCALE
let invertedTransform = CGAffineTransform.inverted(imageView.transform)
for eachSubview in imageView.subviews{
let angle = atan2f(Float(eachSubview.transform.b), Float(eachSubview.transform.a));
eachSubview.transform = invertedTransform().rotated(by: CGFloat(angle))
}
playVibrate()
presentPullViewForMarker(btnMarker: btnMarker)
// btnMarker.applyBorderDefault() }
func playVibrate(){
// AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); }
func presentPullViewForMarker(btnMarker:UIButton){
self.selectedBtnMarker = btnMarker
self.showPullViewAtBottom(animated: true)
(viewHeader.subviews.first as! UIButton).setTitle("Add Photos for : \((btnMarker.titleLabel?.text)!)", for: .normal)
}
//MARK:- BUTTON EVENTS
func btnMarkerTapHandler(_ sender:UIButton){
self.presentPullViewForMarker(btnMarker: sender)
}
func btnAddPhotosTapHandler(_ sender:UIButton){
saveMarkerInDefault()
// let secondVC = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
// self.navigationController?.pushViewController(secondVC, animated: true)
// self.present(secondVC, animated: true) {
//
// }
}
func btnRemoveMarkerTapHandler(_ sender:UIButton){
if let selectedBtnMarker = self.selectedBtnMarker {
showAlertWithTitle(title: "Remove Marker \((selectedBtnMarker.titleLabel?.text)!)", message: "Are you sure you want to remove this marker ?", buttons: ["Cancel","Yes"], showsCancelOption: false, completion: { (selectedIndex) in
if(selectedIndex == 1){
if let validIndex = self.arrPlacedMarkers.index(of: selectedBtnMarker){
self.arrPlacedMarkers.remove(at: validIndex)
self.selectedBtnMarker?.removeFromSuperview()
DispatchQueue.main.async {
self.configurator.hide(animated: true)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.4) {
self.hidePullViewFromBottom(animated: true)
}
}
}
}
})
}
}
//MARK:-
func btnRotateLeftHandler(sender:UIButton){
if let selectedBtnMarker = self.selectedBtnMarker {
selectedBtnMarker.rotate(angle: -5)
}
}
func btnRotateRightHandler(sender:UIButton){
if let selectedBtnMarker = self.selectedBtnMarker {
selectedBtnMarker.rotate(angle: 5)
}
}
//MARK:-
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.backgroundColor = UIColor.clear
cell.textLabel?.textColor = UIColor.gray
cell.textLabel?.text = "Photo \(indexPath.row + 1)"
return cell;
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
viewHeader = UIView(frame: CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: 100))
viewHeader.backgroundColor = UIColor.lightGray
let btnAddPhotos = UIButton(forAutoLayout: ())
btnAddPhotos.setTitle("Add Photos", for: .normal)
btnAddPhotos.addTarget(self, action: #selector(self.btnAddPhotosTapHandler(_:)), for: .touchUpInside)
viewHeader.addSubview(btnAddPhotos)
btnAddPhotos.autoCenterInSuperview()
return viewHeader
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return GET_PROPORTIONAL_HEIGHT(height: 40)
}
//MARK:-
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.configurator.handleTouchesBegan(touches)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
self.configurator.handleTouchesMoved(touches)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.configurator.handleTouchesEnded(touches)
}
//MARK:- AGPullView DELEGATES
func didDrag(_ pullView: AGPullView!, withOpeningPercent openingPercent: Float) {
// print("did drag : (openingPercent)") openingPercent > 0.0 ? hideRotateButtons(withAnimation: true) : showRotateButtons(withAnimation: true) }
func didShow(_ pullView: AGPullView!) {
print("shown");
isPullViewOpened = true
table.isUserInteractionEnabled = true
hideRotateButtons(withAnimation: true)
}
func didHide(_ pullView: AGPullView!) {
print("hidden")
isPullViewOpened = false
table.isUserInteractionEnabled = false
showRotateButtons(withAnimation: true)
}
func didTouch(toShow pullView: AGPullView!) {
print("touched to show")
}
func didTouch(toHide pullView: AGPullView!) {
print("touched to hide")
}
//MARK:- PAN GESTURE HANDLER
func panGestureHandler(_ recognizer:UIPanGestureRecognizer){
if(recognizer.state == .changed || recognizer.state == .ended) {
let draggedButton = recognizer.view
var newFrame = draggedButton?.frame
if(newFrame!.origin.x < 0.0){
newFrame!.origin.x = 0.0
}
if(newFrame!.origin.y < 0.0){
newFrame!.origin.y = 0.0
}
let oldXPlusWidth = newFrame!.origin.x + newFrame!.size.width
let trailingMarginToKeep = self.imageView.bounds.size.width - newFrame!.size.width
if(oldXPlusWidth > self.imageView.bounds.size.width){
newFrame!.origin.x = trailingMarginToKeep
}
let oldYPlusHeight = newFrame!.origin.y + newFrame!.size.height
let bottomMarginToKeep = self.imageView.bounds.size.height - newFrame!.size.height
if(oldYPlusHeight > self.imageView.bounds.size.height){
newFrame!.origin.y = bottomMarginToKeep
}
let translationPoint = recognizer.translation(in: self.imageView)
newFrame?.origin.x += translationPoint.x
newFrame?.origin.y += translationPoint.y
let centerX:CGFloat = newFrame!.origin.x + (newFrame!.size.width/2)
let centerY:CGFloat = newFrame!.origin.y + (newFrame!.size.height/2)
draggedButton?.center = CGPoint(x: centerX, y: centerY)
recognizer.setTranslation(CGPoint.zero, in: self.imageView)
}
}
//MARK:- ROTATION GESTURE HANDLER
func rotationGestureHandler(_ recognizer:UIRotationGestureRecognizer){
recognizer.view!.transform = recognizer.view!.transform.rotated(by: recognizer.rotation)
recognizer.rotation = 0
}
//MARK:- LONG PRESS HANDLER
func longPressHandlerForMapImageView(_ sender:UILongPressGestureRecognizer){
if sender.state == .began{
// self.addButtonWithAtPoint(touchedPoint: sender.location(in: sender.view)) self.addButtonWithAtPoint(touchedPoint: sender.location(in: imageView)) } }
func longPressHandlerForRotateLeftButton(_ sender:UILongPressGestureRecognizer){
switch sender.state {
case .began:
self.timerRotateButtons = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.timerHandlerForRotateButton(sender:)), userInfo: sender.view, repeats: true)
case .ended:
self.timerRotateButtons.invalidate()
self.timerRotateButtons = nil
default:
break
}
}
func longPressHandlerForRotateRightButton(_ sender:UILongPressGestureRecognizer){
switch sender.state {
case .began:
self.timerRotateButtons = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.timerHandlerForRotateButton(sender:)), userInfo: sender.view, repeats: true)
case .ended:
self.timerRotateButtons.invalidate()
self.timerRotateButtons = nil
default:
break
}
}
//MARK:- TIMER
func timerHandlerForRotateButton(sender:Timer){
if let btn:UIButton = sender.userInfo as? UIButton{
var rotateAngle:CGFloat = 0
if(btn == btnRotateLeft){
rotateAngle = -1
}else if(btn == btnRotateRight){
rotateAngle = 1
}
if let selectedBtnMarker = self.selectedBtnMarker {
selectedBtnMarker.rotate(angle: rotateAngle)
}
}
}
//MARK:- TAP GESTURE HANDLER
func singleTapHandler(_ sender:UITapGestureRecognizer){
// print("SINGLE TAP")
if(self.isPullViewOpened){
// print("SINGLE TAP : don't close.. opened") }else{ self.hidePullViewFromBottom(animated: true) }
}
func doubleTapHandler(_ sender:UITapGestureRecognizer){
// print("DOUBLE TAP (scrollView.minimumZoomScale) (scrollView.maximumZoomScale) (scrollView.zoomScale)")
// ZOOM RESET
if(scrollView.zoomScale > scrollView.minimumZoomScale){
scrollView.setZoomScale(scrollView.minimumZoomScale, animated: true)
}else{
// ZOOM IN
let zoomRect = self.zoomRectForScale(scale: DEFAULT_ZOOM_SCALE, withCenter: sender.location(in: sender.view))
scrollView.zoom(to: zoomRect, animated: true)
}
}
func zoomRectForScale(scale:CGFloat, withCenter center:CGPoint) -> CGRect {
var zooomRect:CGRect = CGRect()
zooomRect.size.height = imageView.frame.size.height / scale
zooomRect.size.width = imageView.frame.size.width / scale
let tempCenter = imageView.convert(center, from: self.imageView)
zooomRect.origin.x = tempCenter.x - (zooomRect.size.width / 2.0)
zooomRect.origin.y = tempCenter.y - (zooomRect.size.height / 2.0)
return zooomRect
}
//MARK:- BUTTION EVENTS
@IBAction func btnTestPressed(_ sender: Any) {
// print("BTN 10 % TAP")
showAlertWithTitle(title: "title", message: "message", buttons: ["b1","b2"], showsCancelOption: false) { (selecgtedIndex) in
print("selected \(selecgtedIndex)")
}
}
@IBAction func btnTest1Pressed(_ sender: Any) {
// print("\n\nBTN 90 % TAP")
}
@IBAction func btnTest2Pressed(_ sender: Any) {
// print("BTN RESET TAP")
scrollView.setZoomScale(1, animated: true)
}
//MARK:- SCROLLVIEW DELEGATE
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// print("\n\n(#function) (scrollView.zoomScale) __ (scrollView.contentSize) __ (scrollView.contentOffset) \n")
let invertedTransform = CGAffineTransform.inverted(imageView.transform)
for eachSubview in imageView.subviews{
let angle = atan2f(Float(eachSubview.transform.b), Float(eachSubview.transform.a));
eachSubview.transform = invertedTransform().rotated(by: CGFloat(angle))
}
if(self.isPullViewOpened){
// print("scroll : don't close.. opened") }else{ self.hidePullViewFromBottom(animated: true) } }
//MARK:-
func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
print("\n\(#function)\n")
return false
}
// func scrollViewDidScrollToTop(_ scrollView: UIScrollView) {
// print("\n(#function)\n")
// }
//
//
// //MARK:-
// func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
// print("\n(#function)\n")
// }
//MARK:-
// func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
// print("\n(#function)\n")
// }
// func scrollViewDidZoom(_ scrollView: UIScrollView) {
// print("\n(#function) (scrollView.zoomScale) __ (scrollView.contentSize) __ (scrollView.contentOffset) ")
// }
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
// print("\n(#function)\n")
let invertedTransform = CGAffineTransform.inverted(imageView.transform)
for eachSubview in imageView.subviews{
let angle = atan2f(Float(eachSubview.transform.b), Float(eachSubview.transform.a));
eachSubview.transform = invertedTransform().rotated(by: CGFloat(angle))
}
// for i in 0..
// for i in 0..
}
//MARK:-
// func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { // print("\n(#function)\n") // } // func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { // print("\n(#function)\n") // } // func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { // print("\n(#function)\n") // } // func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) { // print("\n(#function)\n") // } // func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { // print("\n(#function)\n") // }
}
来源:https://stackoverflow.com/questions/6693527/how-to-use-rotation-and-translation-for-an-image-simultaneously-in-iphone