I have UIWebView and in its scrollView, I added a UIImageView like so:
self.webview.scrollView.addSubview(image)
my problem is when I rotate my device from portrait to landscape the UIImageView does not stay at the position I originally set it to on the scrollView, I understand the width and height of the screen change, I guess what I am trying to do it change the the position on my UIImageView so it appears it did not change.
I have this method in place:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
var newScrollViewFrame = webview.scrollView.frame
var newFrame = webview.frame
newFrame.size.width = size.width
newFrame.size.height = size.height
newScrollViewFrame.size.width = size.width
newScrollViewFrame.size.height = size.height
webview.frame = newFrame
webview.scrollView.frame = newScrollViewFrame
}
The current code inside this method just resize the UIWebView and its scroll view, but not the UIImageViews in the scrollView
Any help would be appreciated.
Thanks,
I have tried the following:
for views in webview.scrollView.subviews
{
if(views.isKindOfClass(UIImageView))
{
views.transform = CGAffineTransformMakeRotation(CGFloat(M_PI)/2);
}
}
but this puts on UIImageView sideways on rotate
Here is how I am adding the webview to the view:
webview = UIWebView()
webview.frame = self.view.bounds
webview.scrollView.frame = webview.frame
webview.userInteractionEnabled = true
webview.scalesPageToFit = true
webview.becomeFirstResponder()
webview.delegate = self
webview.scrollView.delegate = self
self.view.addSubview(webview)
I have half solved my problem, but doing the following:
webview.translatesAutoresizingMaskIntoConstraints = false
let horizontalConstraint = NSLayoutConstraint(item: webview, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)
view.addConstraint(horizontalConstraint)
let verticalConstraint = NSLayoutConstraint(item: webview, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0)
view.addConstraint(verticalConstraint)
let widthConstraint = NSLayoutConstraint(item: webview, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0.1, constant: 500)
view.addConstraint(widthConstraint)
let heightConstraint = NSLayoutConstraint(item: webview, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 500)
view.addConstraint(heightConstraint)
However now, the UIWebView is not full width or height :( Sooooo close.
I also tried this, but the UIImageView do not remain in the same spot.
let left = NSLayoutConstraint(item: self.webView, attribute: .Left, relatedBy: .Equal, toItem: self.view, attribute: .Left, multiplier: 1, constant: 0)
let right = NSLayoutConstraint(item: self.webView, attribute: .Right, relatedBy: .Equal, toItem: self.view, attribute: .Right, multiplier: 1, constant: 0)
let top = NSLayoutConstraint(item: self.webView, attribute: .Top, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 0)
let bottom = NSLayoutConstraint(item: self.webView, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1, constant: 0)
NSLayoutConstraint.activateConstraints([top, bottom, left, right])
I have also tried adding constraints to the UIImageView
let stampView:StampAnnotation = StampAnnotation(imageIcon: UIImage(named: "approved.png"), location: CGPointMake(currentPoint.x, currentPoint.y))
self.webview.scrollView.addSubview(stampView)
let left = NSLayoutConstraint(item: stampView, attribute: .Left, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Left, multiplier: 1, constant: 0)
let right = NSLayoutConstraint(item: stampView, attribute: .Right, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Right, multiplier: 1, constant: 0)
let top = NSLayoutConstraint(item: stampView, attribute: .Top, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Top, multiplier: 1, constant: 0)
let bottom = NSLayoutConstraint(item: stampView, attribute: .Bottom, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Bottom, multiplier: 1, constant: 0)
NSLayoutConstraint.activateConstraints([top, bottom, left, right])
same result, UIImageView does not stay in the same spot.
UPDATE
My webview:
webview = UIWebView()
webview.userInteractionEnabled = true
webview.scalesPageToFit = true
webview.becomeFirstResponder()
webview.delegate = self
webview.scrollView.delegate = self
self.view.addSubview(webview)
webview.loadRequest(NSURLRequest(URL:url))
webview.gestureRecognizers = [pinchRecognizer, panRecognizer]
webview.translatesAutoresizingMaskIntoConstraints = false
let left = NSLayoutConstraint(item: webview, attribute: .Left, relatedBy: .Equal, toItem: self.view, attribute: .Left, multiplier: 1, constant: 0)
let right = NSLayoutConstraint(item: webview, attribute: .Right, relatedBy: .Equal, toItem: self.view, attribute: .Right, multiplier: 1, constant: 0)
let top = NSLayoutConstraint(item: webview, attribute: .Top, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 0)
let bottom = NSLayoutConstraint(item: webview, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1, constant: 0)
NSLayoutConstraint.activateConstraints([top, bottom, left, right])
UIImageView
stampView.translatesAutoresizingMaskIntoConstraints = false
let left = NSLayoutConstraint(item: stampView, attribute: .Left, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Left, multiplier: 1, constant: 100)
let right = NSLayoutConstraint(item: stampView, attribute: .Right, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Right, multiplier: 1, constant: 0)
let top = NSLayoutConstraint(item: stampView, attribute: .Top, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Top, multiplier: 1, constant: 100)
let bottom = NSLayoutConstraint(item: stampView, attribute: .Bottom, relatedBy: .Equal, toItem: self.webview.scrollView, attribute: .Bottom, multiplier: 1, constant: 0)
let width = NSLayoutConstraint(item: stampView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 0.1, constant: 150)
let height = NSLayoutConstraint(item: stampView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 73)
NSLayoutConstraint.activateConstraints([left, right, top, bottom, width, height])
I just need to figure out the math to have this device be at the position of touch. (in percentages ?)
I think these things are always easier to do without using autolayout. To do this, I recomend using viewDidLayoutSubviews(). Here is my code:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
webView.frame = view.bounds
let screen = UIScreen.mainScreen().fixedCoordinateSpace
//These values will give a rect half the size of the screen and centered.
let width = screen.bounds.width / 2
let height = screen.bounds.height / 2
let x = (screen.bounds.width - width) / 2
let y = (screen.bounds.height - height) / 2
let absoluteRect = CGRect(x: x, y: y, width: width, height: height)
let stampRect = screen.convertRect(absoluteRect, toCoordinateSpace: webView)
stampView.frame = stampRect
//Change the orientation of the image
switch UIDevice.currentDevice().orientation {
case .LandscapeLeft:
stampView.image = UIImage(CGImage:originalImage.CGImage!, scale:originalImage.scale, orientation: UIImageOrientation.Left)
break
case .LandscapeRight:
stampView.image = UIImage(CGImage:originalImage.CGImage!, scale:originalImage.scale, orientation: UIImageOrientation.Right)
break
default:
stampView.image = UIImage(CGImage:originalImage.CGImage!, scale:originalImage.scale, orientation: UIImageOrientation.Up)
break
}
}
I am doing several things here...First I set the webViewFrame. Next, it is helpful here to define an absolute coordinate system relative to your screen. When the phone orientation changes, the values of screen will not change (allowing you to keep your imageView in the same place.) Next I define the desired frame for the stampView, then convert the absolute frame into its equivalent inside your scrollView (it's superView) and assign it to the stampView. Finally, if you want the image in your stampView to always be oriented correctly, you need to change the image orientation. CGAffineTransformMakeRotation only works if your view is square, but we can make it more general by actually changing the imageOrientation within the stampView. This requires a property for the original image:
let originalImage = UIImage(named: "image_name")!
Finally, because viewWillLayoutSubViews() is not called for landscape to landscape transitions, do the following:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
view.setNeedsLayout()
}
This code doesn't make for the prettiest transitions, it should help with your layout problems.
To make the UIImageView
keep the same size and stay in the same position relative to the UIWebView
, you can set your views to be a percentage of their respective superView
. Here I've created some mock views that illustrate the basic idea:
import UIKit
class ViewController: UIViewController {
//we create some views for testing and create references to the size and points we need for positioning
let webView = UIWebView()
let image = UIImageView()
let image2 = UIImageView()
var imageViewSize = CGSize()
var imageViewCenter = CGPoint()
override func viewDidLoad() {
super.viewDidLoad()
//set webView frame
webView.frame = self.view.bounds
webView.backgroundColor = UIColor.clearColor()
webView.userInteractionEnabled = true
webView.scalesPageToFit = true
webView.opaque = false
self.view.addSubview(webView)
//we will hold onto the original size of the UIImageView for later
imageViewSize = CGSizeMake(webView.bounds.size.width * 0.2, webView.bounds.size.height * 0.1)
//mock UIImageView
image.backgroundColor = UIColor.orangeColor()
image.frame.size = CGSizeMake(imageViewSize.width, imageViewSize.height)
image.center = CGPointMake(webView.bounds.size.width / 2, webView.bounds.size.height / 2)
webView.scrollView.addSubview(image)
//I've created a subset image to illustrate the orientation
image2.backgroundColor = UIColor.whiteColor()
image2.frame = CGRectMake(10, 10, 10, 10)
image.addSubview(image2)
}
And then change the frame when rotated (Notice that the position on the UIImageView
and the width of the UIWebView
are set relative to the height of their superView
s and vice versa since the device is rotated):
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
image.frame.size = CGSizeMake(imageViewSize.width, imageViewSize.height)
image.center = CGPointMake(webView.bounds.size.height / 2, webView.bounds.size.width / 2)
webView.frame = CGRectMake(0, 0, self.view.bounds.size.height, self.view.bounds.size.width)
webView.scrollView.contentSize = webView.frame.size
}
}
Since you are creating the position and sizes of your views as percentages of their superView
s, the code will play nicer with different device sizes (i.e. iPhone/iPad).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With