GJNilsen/YPMagnifyingGlass

Swift 2.0

Closed this issue · 6 comments

Some modifications are needed for this to work properly in Swift 2.0
`//
// YPMagnifyingView.swift
// YPMagnifyingGlass
//
// Created by Geert-Jan Nilsen on 02/06/15.
// Copyright (c) 2015 Yuppielabel.com All rights reserved.
//

import UIKit

public class YPMagnifyingView: UIView {

public var YPMagnifyingViewDefaultShowDelay: NSTimeInterval = 0.2;

private var magnifyingGlassShowDelay: NSTimeInterval

private var touchTimer: NSTimer!

public var magnifyingGlass: YPMagnifyingGlass = YPMagnifyingGlass()

override public init(frame: CGRect) {
self.magnifyingGlassShowDelay = YPMagnifyingViewDefaultShowDelay
super.init(frame: frame)
}

required public init?(coder aDecoder: NSCoder) {
self.magnifyingGlassShowDelay = YPMagnifyingViewDefaultShowDelay
super.init(coder: aDecoder)
}

// MARK: - Touch Events
override public func touchesBegan(touches: Set, withEvent event: UIEvent?) {
if let touch: UITouch = touches.first {

  self.touchTimer = NSTimer.scheduledTimerWithTimeInterval(magnifyingGlassShowDelay, target: self, selector: Selector("addMagnifyingGlassTimer:"), userInfo: NSValue(CGPoint: touch.locationInView(self)), repeats: false)
}

}

override public func touchesMoved(touches: Set, withEvent event: UIEvent?) {
if let touch: UITouch = touches.first {
self.updateMagnifyingGlassAtPoint(touch.locationInView(self))
}
}

override public func touchesEnded(touches: Set, withEvent event: UIEvent?) {
self.touchTimer.invalidate()
self.touchTimer = nil

self.removeMagnifyingGlass()

}

// MARK: - Private Functions

private func addMagnifyingGlassAtPoint(point: CGPoint) {
self.magnifyingGlass.viewToMagnify = self as UIView
self.magnifyingGlass.touchPoint = point

let selfView: UIView = self as UIView

// let superView: UIView = self.superview!

selfView.addSubview(self.magnifyingGlass)

self.magnifyingGlass.setNeedsDisplay()

}

private func removeMagnifyingGlass() {
self.magnifyingGlass.removeFromSuperview()
}

private func updateMagnifyingGlassAtPoint(point: CGPoint) {
self.magnifyingGlass.touchPoint = point
self.magnifyingGlass.setNeedsDisplay()
}

public func addMagnifyingGlassTimer(timer: NSTimer) {
let value: AnyObject? = timer.userInfo
if let point = value?.CGPointValue {
self.addMagnifyingGlassAtPoint(point)
}
}
}
//
// YPMagnifyingGlass.swift
// YPMagnifyingGlass
//
// Created by Geert-Jan Nilsen on 02/06/15.
// Copyright (c) 2015 Yuppielabel.com All rights reserved.
//

import UIKit
import QuartzCore

public class YPMagnifyingGlass: UIView {

public var viewToMagnify: UIView!
public var touchPoint: CGPoint! {
didSet {
self.center = CGPointMake(touchPoint.x + touchPointOffset.x, touchPoint.y + touchPointOffset.y)
}
}

public var touchPointOffset: CGPoint!
public var scale: CGFloat!
public var scaleAtTouchPoint: Bool!

public var YPMagnifyingGlassDefaultRadius: CGFloat = 40.0
public var YPMagnifyingGlassDefaultOffset: CGFloat = -40.0
public var YPMagnifyingGlassDefaultScale: CGFloat = 2.0

public func initViewToMagnify(viewToMagnify: UIView, touchPoint: CGPoint, touchPointOffset: CGPoint, scale: CGFloat, scaleAtTouchPoint: Bool) {

self.viewToMagnify = viewToMagnify
self.touchPoint = touchPoint
self.touchPointOffset = touchPointOffset
self.scale = scale
self.scaleAtTouchPoint = scaleAtTouchPoint

}

required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

required public override init(frame: CGRect) {
super.init(frame: frame)

self.layer.borderColor = UIColor.lightGrayColor().CGColor
self.layer.borderWidth = 3
self.layer.cornerRadius = frame.size.width / 2
self.layer.masksToBounds = true
self.touchPointOffset = CGPointMake(0, YPMagnifyingGlassDefaultOffset)
self.scale = YPMagnifyingGlassDefaultScale
self.viewToMagnify = nil
self.scaleAtTouchPoint = true

}

private func setFrame(frame: CGRect) {
super.frame = frame
self.layer.cornerRadius = frame.size.width / 2
}

public override func drawRect(rect: CGRect) {
let context: CGContextRef = UIGraphicsGetCurrentContext()!
CGContextTranslateCTM(context, self.frame.size.width/2, self.frame.size.height/2)
CGContextScaleCTM(context, self.scale, self.scale)
CGContextTranslateCTM(context, -self.touchPoint.x, -self.touchPoint.y + (self.scaleAtTouchPoint != nil ? 0 : self.bounds.size.height/2))
self.viewToMagnify.layer.renderInContext(context)
}
}
`

override public func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { if let touch: UITouch = touches.first { self.updateMagnifyingGlassAtPoint(touch.locationInView(self)) } }

Original post removed the code for the override function

Great job! Could you make a fork and submit a pull request? That would be the proper way to add your code for historical reasons.

beckp commented

I am trying to create a magnification loupe that already appears on the display when a view loads. The user is instructed to move the loupe to a specific point over an x-ray. While this loupe is similar to those written in Objective-C, I am new to coding and am trying to create in Swift. Further, I am not trying to create a loupe like Apple made to see text, this loupe does not need to move out of the way of the finger tip.

My goal with this part of the app is to place a loupe over an x-ray and have the user move the loupe to a specific point of on the x-ray. I was able to create the loupe using CG paths and the shadow using CALayer. I can pan it and track the center of the crosshairs. However, I need is to be able to magnify the image within the loupe so that the user can more accurately identify a specific point on the image.

I am stumbling is getting the radiographic image into my custom class where I perform the override func draw(rect: ), scale, and crop/mask to the loupe.

I have been able to use CGContext to scale and translate items that I have created using paths. But I have not been able to figure out how to do this with UIImages and then get them to live update as the user pans.

Pannable Loupe with Crosshairs; Magnification within Loupe Not Depicted
thumb_img_8880_1024

Sorry, but this project has not the highest priority at the moment, and no time allotted to it. Im already struggling with a backlog on my open source projects.

beckp commented

No problem. I appreciate the rapid response.

Sent from my iPad

On Sep 30, 2016, at 4:56 PM, GJ Nilsen notifications@github.com wrote:

Sorry, but this project has not the highest priority at the moment, and no time allotted to it. Im already struggling with a backlog on my open source projects.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.