Add annotation to resizable image within scrollview - swift

I have a Scroll View in which I load an Image that can be zoomed and where I can "navigate".
I'm trying to add buttons programmatically to the view such as MKAnnotation that are used in MapKit.
Is that possible?
The methods I use are scrollViewDidZoom
func scrollViewDidZoom(scrollView: UIScrollView) {
centerScrollViewContents()
}
where the function centerScrollViewContents is
func centerScrollViewContents() {
let boundsSize = scrollView.bounds.size
var contentFrame = imageView.frame
if contentFrame.size.width < boundsSize.width {
contentFrame.origin.x = (boundsSize.width - contentFrame.size.width) / 2
} else { contentFrame.origin.x = 0 }
if contentFrame.size.height < boundsSize.height {
contentFrame.origin.y = (boundsSize.height - contentFrame.size.height) / 2
} else { contentFrame.origin.y = 0 }
imageView.frame = contentFrame
}
I add the button/annotation with a UITapGestureRecognizer implemented as
let posTocco = sender.locationInView(scrollView)
println("\(posTocco), \(scrollView.zoomScale)")
var button = UIButton()
let image = UIImage(named: "arrow.png") as UIImage?
button.frame = CGRectMake(posTocco.x, posTocco.y, 30, 30)
button.setImage(image, forState: .Normal)
scrollView.addSubview(button)
For sure I need to define the button/annotation outside the tapGesture function but I cannot figure out how to move the button within the image zoom.
Any help?
EDIT:
I partially figured out how to solve this, but the button slightly move at the first zoom in/out.
I create a new variable which stores the latest zoomValue fattoreScalaCorrente and in the scrollViewDidZoom(scrollView:) I do the magic
var newLoc = CGPoint(x: posAssolute.x * scrollView.zoomScale, y: posAssolute.y * scrollView.zoomScale)
button.frame = CGRectMake(newLoc.x, newLoc.y, button.frame.width, button.frame.height)
Do you have any idea why my button is moving slightly at the first zoom?
EDIT2:
After the suggestion given using
button.frame = CGRectMake(newLoc.x - button.frame.width/2, newLoc.y - button.frame.height/2, button.frame.width, button.frame.height)
The button seems to move a little and I cannot understand why.

Try to replace
button.frame = CGRectMake(newLoc.x, newLoc.y, button.frame.width, button.frame.height)
with
button.frame = CGRectMake(newLoc.x - button.frame.width/2, newLoc.y - button.frame.height/2, button.frame.width, button.frame.height)

Related

make disable , ui button random position swift

there is a UIButton in view controller and when button clicked , UIButton move with random position in View Controller . The question it is how i can make disable movable ability when clicked again on button ?
this is moveable Method :
func randomPosition() {
self.movable_Button.layer.cornerRadius = 10
let buttonWidth = movable_Button.frame.width
let buttonHeight = movable_Button.frame.height
let viewWidth = movable_Button.superview!.bounds.width
let viewHeight = movable_Button.superview!.bounds.height
let xwidth = viewWidth - buttonWidth
let yheight = viewHeight - buttonHeight
let xPosition = CGFloat(arc4random_uniform(UInt32(xwidth)))
let yPosition = CGFloat(arc4random_uniform(UInt32(yheight)))
movable_Button.center.x = xPosition + buttonWidth / 2
movable_Button.center.y = yPosition + buttonHeight / 2
}
I think you have programmed something like
func onButtonClicked() {
randomPosition()
}
so you can make a new variable:
var clickedButton = false
func onButtonClicked() { // i know this is not the correct function, but i think you know what i mean ;)
if clickedButton == false {
randomPosition()
} else {
clickedButton = true
}
}

Swift ImageCropper returns an image outside of the specified "window"

I am making an app that has a UIWebView along with a button on a single view controller. When the button is clicked, an image (of the UIWebView) is captured using UIGraphicsContext.
This part works great! But when the button is clicked, after capturing the image, it displays the image as a subview on the same view, and I have been trying to use an ImageCropper Library that draws a CGRect in another subview over the UIImageView on the screen with a submit button. The rectangle itself can be resized (dragging the corners/edges) and moved around the view.
When the submit button is clicked, another subview is displayed in the top left hand portion of screen and display the image that was cropped (after clicking submit button) The idea is to only capture what is inside the rectangle. I am able to get the code working but the image captured is of the same image but not a section that is inside the CGRect.
I have 3 images that show how it works and shows the image that is cropped incorrectly.enter image description here . Shot 1 . Shot 2
Shot 3. I believe my problems lies within the size of image captured and the size of the image with the crop rect are not equal and that is why it is distorting it.
Does anyone know what might be the cause? Sorry for the long winded question but any help would be greatly appreciated!
Here is my code below:
ViewController.swift:
class ViewController: UIViewController {
#IBOutlet var webView: UIWebView!
#IBOutlet var imageView: UIImageView!
override func viewDidLoad() {
imageView.isHidden = true
let aString = URL(string: "https://www.kshuntfishcamp.com/home.page")
webView.loadRequest(URLRequest(url: aString!))
super.viewDidLoad()
}
#IBAction func takePhotoPressed(_ sender: UIButton) {
UIGraphicsBeginImageContextWithOptions(webView.bounds.size, false, 0.0)
if let aContext = UIGraphicsGetCurrentContext(){
webView.layer.render(in: aContext)
}
let capturedImage:UIImage? = UIGraphicsGetImageFromCurrentImageContext()
imageView = UIImageView(frame: CGRect(x: 22, y: 123, width: 330, height: 330))
let image = capturedImage
imageView.image = image
imageView.contentMode = UIViewContentMode.scaleAspectFill
imageView.clipsToBounds = true
imageView.isHidden = true
webView.isHidden = true
let editView = EditImageView(frame: self.view.frame)
let image2 = capturedImage!
editView.initWithImage(image: image2)
let croppedImage = editView.getCroppedImage()
self.view.addSubview(editView)
self.view.backgroundColor = UIColor.clear
UIImageWriteToSavedPhotosAlbum(croppedImage, nil, nil, nil)
}
EditImageView.swift - source (https://github.com/Thanatos-L/LyEditImageView)-only including parts that seem relevant to solving the problem
func initWithImage(image:UIImage){
imageView = UIImageView(frame: CGRect(x: 22, y: 123, width: 330, height: 330))
imageView.tag = IMAGE_VIEW_TAG;
self.addSubview(self.imageView)
imageView.isUserInteractionEnabled = true;
imageView.image = image
imageView.frame = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
let frame = AVMakeRect(aspectRatio: imageView.frame.size, insideRect: self.frame);
imageView.frame = frame
originImageViewFrame = frame
NSLog("initWithImage %#", NSStringFromCGRect(originImageViewFrame))
imageZoomScale = 1.0
commitInit()
}
private func cropImage() {
let rect = self.convert(cropView.frame, to: imageView)
let imageSize = imageView.image?.size
let ratio = originImageViewFrame.size.width / (imageSize?.width)!
let zoomedRect = CGRect(x: rect.origin.x / ratio, y: rect.origin.y / ratio, width: rect.size.width / ratio, height: rect.size.height / ratio)
let croppedImage = cropImage(image: imageView.image!, toRect: zoomedRect)
var view: UIImageView? = self.viewWithTag(1301) as? UIImageView
if view == nil {
view = UIImageView()
}
view?.frame = CGRect(x: 0, y: 0, width: croppedImage.size.width , height: croppedImage.size.height)
view?.image = croppedImage
view?.tag = 1301
self.addSubview(view!)
}

Create UILabel at TopLeft of UIVIew and animate straight downwards?

Iv been working on this new game for a couple months now and run into a problems I cant figure out!
So basically I am creating a "status section" in the top right of my UIViewController. In this "status section" will appear UILabels that hold status updates as Strings. These UILabels will appear at the very top left of the UIView and will go slowly downwards and lose Alpha at the same time..eventually dissappearing once it reaches the bottom.
What Iv Done?
So as you can see in the code before so far Iv been able to create the UILabel at random locations but for some reason the UILabels spawn off screen.
Code
func createStatus() {
let viewWidth = self.statusView.frame.width
let viewHeight = self.statusView.frame.width
let randomX = CGFloat(viewWidth / 2)
let randomY = CGFloat(arc4random_uniform(UInt32(viewHeight)) + 50)
let frame = self.statusView.frame.origin
let status = UILabel(frame: CGRect(origin: CGPoint(x: CGFloat(viewWidth / 4) - 20, y: CGFloat(viewHeight - viewHeight) + 10), size: CGSize(width: 200.0, height: 50.0)))
status.text = "This is a status"
status.textColor = UIColor.redColor()
status.alpha = 1
self.statusView.addSubview(status)
print("Status made")
UIView.animateWithDuration(2) {
status.center = frame
status.alpha = 0
}
}
Iv added an image of the problem and the UIViewstatusView as well. Im having trouble making the UILabel at the top left and i'v tried this code below and it doesnt even "spawn" the UILabel on the screen.
let frame = self.statusView.frame.origin
CGPoint topLeft = CGPointMake(CGRectGetMinX(frame), CGRectGetMinY(frame));
func createStatus() {
let viewWidth = self.statusView.frame.width
let viewHeight = self.statusView.frame.width
//Why are these here?
let randomX = CGFloat(viewWidth / 2)
let randomY = CGFloat(arc4random_uniform(UInt32(viewHeight)) + 50)
let origin = CGPointZero//Origins are relative to superview, so top left would be (0, 0)
//Renamed status to statusLabel so that we know its a label and not a model object
let statusLabel = UILabel(frame: CGRect(origin: origin, size: CGSize(width: 200.0, height: 50.0)))
statusLabel.text = "This is a status"
statusLabel.textColor = UIColor.redColor()
statusLabel.alpha = 1
self.statusView.addSubview(statusLabel)
print("Status made")
UIView.animateWithDuration(2) {
//Animate the origin instead of center position.
//The origin will be the height of the statusView - the height of your label. x stays 0 to keep it along left edge.
statusLabel.frame.origin = CGPoint(x: 0, y: self.statusView.frame.height - statusLabel.frame.height )
statusLabel.alpha = 0
}, { (completed) in
if completed {
//If statusLabel doesn't have a superView it will be dealloc after the function goes out of scope. So remove it from superview after animaion is complete and ARC takes care of it.
statusLabel.removeFromSuperview()
}
}
}

How can I factorize a panGestureHandling Function in Swift for UILabel and UIImageView types?

I building a photo collage app and have UILabel and UIImageView elements that I would like to add Gesture Recognizers to. Currently, I am handling the PanGestures for each type in two different functions since I need to declare the type of the panGesture.view as either UILabel or UIImageView:
func handlePanGesture(panGesture: UIPanGestureRecognizer!) {
// Get translation
var translation = panGesture.translationInView(view)
panGesture.setTranslation(CGPointZero, inView: view)
panGesture.delegate = self
// Add dx,dy to current image position
var image = panGesture.view as! UIImageView
image.center = CGPoint(x: image.center.x + translation.x, y: image.center.y + translation.y)
}
func handlePanGestureText(panGesture: UIPanGestureRecognizer!) {
var translation = panGesture.translationInView(view)
panGesture.setTranslation(CGPointZero, inView: view)
panGesture.delegate = self
var label = panGesture.view as! UILabel
label.center = CGPoint(x: label.center.x + translation.x, y: label.center.y + translation.y)
}
Is it possible to factorize this code and put it all in one function and use it for both types? (e.g. if UIPanGestureRecognizer = UILabel {
...}
Best,
Max
Here sample code from Apple :
https://developer.apple.com/library/ios/samplecode/Touches/Listings/Touches_GestureRecognizers_Touches_APLAppDelegate_m.html#//apple_ref/doc/uid/DTS40007435-Touches_GestureRecognizers_Touches_APLAppDelegate_m-DontLinkElementID_6

How do I connect my scrollView with my PageController? (Swift)

Okay So I'm having real trouble trying to get my pageControl to cooperate with my scroll. I tried different functions but I can seem to get it right. I'm able to call the right amount of views such as the white dots match the number of pictures I have but the dots don't move when I scroll from one picture to the other. How would you connect my pageControl to my scroll so when I scroll left and right it will respond the the pageControl?
// Number of views
var numberOfViews = picSource.count
var picNum:CGFloat = CGFloat(picSource.count)
// Image Scroller
let scroll = UIScrollView(frame:CGRectMake(-5, 650, screenWidth, 260))
scroll.pagingEnabled = true
scroll.showsHorizontalScrollIndicator = false
scroll.showsVerticalScrollIndicator = false
scroll.contentSize = CGSizeMake(picNum*screenWidth, 220)
scroll.delegate = self
let pageControl = UIPageControl(frame: CGRectMake(0, 600, 100, 25))
pageControl.numberOfPages = numberOfViews
pageControl.currentPage = 0
pageControl.addTarget(self, action: "pageControlSwipe:", forControlEvents: UIControlEvents.ValueChanged)
pageControl.backgroundColor = UIColor.redColor()
pageControl.userInteractionEnabled = true
self.view.bringSubviewToFront(pageControl)
border.addSubview(pageControl)
// pageControl swipe
func pageControlSwipe(sender: AnyObject) -> () {
let x = CGFloat(pageControl.currentPage) * scroll.frame.size.width
scroll.setContentOffset(CGPointMake(x, 0), animated: true)
}
func scrollViewDidEndDecelerating(scroll: UIScrollView) -> () {
let pageNumber = round(scroll.contentOffset.x / (scroll.frame.size.width))
pageControl.currentPage = Int(pageNumber)
}
To Connnect ScrolView With PageController See the link... link here
in this have Main ScrollView -> PageController -> SubScrollView -> UIImageView -> UIImage