Right way to fit image to CALayer contents in swift programmatically? - ios

I am new to programming.
#IBOutlet weak var myView: UIView!
var l: CALayer {
return myView.layer
}
override func viewDidLoad() {
super.viewDidLoad()
setUpLayer()
}
func setUpLayer() {
l.contents = UIImage(named: "IMG_3682.jpg")?.CGImage
l.contentsGravity = kCAGravityCenter
}
The image appears way bigger than myView.
I got imges with various sizes and ratios.
and I want to fit them into UIView.layer
What is the right way to do it?
thanks

Remove line:
l.contentsGravity = kCAGravityCenter

Related

swift UIVisualEffectView with mask autolayout varies by iOS device

I am working with swift UIVisualEffectView with mask option.
I am trying to make a blurred UIVisualEffectView masked by UIImageView.
I've set autolayout constraints to the views at the storyboard but the result varies through the iOS device.
Storyboard, code and results are attached below.
I would be glad if anyone help me.
I've set all auto layout constraints at the storyboard.(Capture included below)
Code is very simple. I've only set blurView.mask = topImageView.
class TestViewController: UIViewController {
#IBOutlet weak var bottomImageView: UIImageView!
#IBOutlet weak var topImageView: UIImageView!
#IBOutlet weak var blurView: UIVisualEffectView!
override func viewDidLoad() {
super.viewDidLoad()
blurView.mask = topImageView
}
// Still same issue when I move the mask to 'viewDidLayoutSubviews()' method
//
// override func viewDidLayoutSubviews() {
// super.viewDidLoad()
// blurView.mask = topImageView
// }
}
Storyboard and Code capture
Results depending on iOS versions
---
I've tried to move mask code from viewDidLoad() method to viewDidLayoutSubviews() but it's still same.
Self-solved by the below code.
Received a hint from similar issue : 'https://stackoverflow.com/questions/58998541/swift-mask-uiview-constraints-issues/59037761'
override func viewDidAppear() {
self.setupBlur()
}

image is not scrolling when both scrollview and image view are in storyboard

I created a sample project using Xcode 8 with a storyboard having a scroll view and image view as subview of scrollview. image view's content mode is set to center. Scrollview doesn't scroll .
![Here are the constraints in the story board:
scrollView]1
Here is the code
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
imageURL = "http://www.hdwallpapers.in/walls/cosmea_floral_bloom-wide.jpg"
}
var imageURL: String? {
didSet {
updateImage()
scrollView.contentSize = imageView.frame.size
}
}
func updateImage() {
if let data = NSData(contentsOf: URL(string:imageURL! )!) {
imageView.image = UIImage(data: data as Data)
imageView.sizeToFit()
}
}
}
However, when I create my imageView programmatically, scrollView works. What am I missing in the above code? code below works
import UIKit
class ImageViewController: UIViewController {
var image: UIImage? {
get {
return imageView.image
}
set {
imageView.image = newValue
imageView.sizeToFit()
}
}
var imageUrl: URL? {
didSet {
image = nil
fetchImage(url: imageUrl)
}
}
func fetchImage(url: URL?) {
let data = NSData(contentsOf: url!)
image = UIImage(data: data as! Data)!
}
var imageView = UIImageView()
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
imageUrl = ImageData.imageURL(for: ImageData.images["imageOne"]!)!
scrollView.addSubview(imageView)
scrollView.contentSize = imageView.frame.size
}
}
You should delete the align center X and align center Y constraints. These constraints are holding your image view in place and not allowing scrolling.
When you delete them you will likely get a constraints error. This is because at design time your layout is ambiguous. The image view's intrinsic size is based on the image, but you want to set your image at run time. To resolve this, you should select your image view, go to the size inspector, click on the intrinsic size drop down menu and set a placeholder size. The placeholder size will only be used at design time and be replaced at run time.

iOS Swift: How to overlay two images that zoom in at same time without loosing coordinates of overlaying image

My problem is pretty simple really...
Imagine a background image that represents the streets and buildings around your house, note that this is a purpose built image. This image (a view) is zoomable and so far so good. Similar to map, but with an image instead.
Now image that on top of the streets drawn on the image there are markers representing cars. These will move over time and therefore will be moving dynamically. I have successfully placed the cars in the right place on the image, but when I zoom in/out the cars move out of place. Note that I don't want the cars to change in size, they will always remain the same.
Essentially, very similar to a map marker on top of google maps, but instead of the map I have a background picture and instead of the markers I have other images (the cars).
Now for the implementation...
I have a simple ScrollableView which contains an image view. I am trying to overlay other multiple pictures that I want to keep placement but not zoom in or out (or at least not as much as the main picture). I would say that it is similar to a map which has location pins on it, but it is just using pictures.
I am doing this in Swift and the latest iOS version (9x)
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate
{
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var pin1View: UIImageView!
#IBOutlet weak var pin2View: UIImageView!
override func viewDidLoad()
{
super.viewDidLoad()
self.scrollView.minimumZoomScale = 1.0;
self.scrollView.maximumZoomScale = 10.0;
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView?
{
let pin1_X = self.pin1View.frame.origin.x
let pin2_Y = self.pin2View.frame.origin.y
//I guess I need to do something here but not sure
return self.imageView
}
}
Any tips much appreciated. I googled it but couldn't find examples and still learning views and swift as well as general mobile dev.
Thanks for your help.
You have the change centre of the pin accordingly. Use this updated code:
class ViewController: UIViewController, UIScrollViewDelegate
{
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var pin1View: UIImageView!
#IBOutlet weak var pin2View: UIImageView!
var pin1ViewCenter : CGPoint = CGPointZero
var pin2ViewCenter : CGPoint = CGPointZero
override func viewDidLoad()
{
super.viewDidLoad()
self.scrollView.scrollEnabled = true
self.scrollView.minimumZoomScale = 1.0
self.scrollView.maximumZoomScale = 10.0
pin1ViewCenter = pin1View.center
pin2ViewCenter = pin2View.center
self.scrollView.contentSize = self.imageView.frame.size
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView?
{
return self.imageView
}
func scrollViewDidZoom(scrollView: UIScrollView) {
let scaleAffineTransform = CGAffineTransformScale(CGAffineTransformIdentity, scrollView.zoomScale, scrollView.zoomScale)
var translatedPoint = CGPointApplyAffineTransform(pin1ViewCenter, scaleAffineTransform)
pin1View.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, translatedPoint.x - pin1ViewCenter.x , translatedPoint.y - pin1ViewCenter.y)
translatedPoint = CGPointApplyAffineTransform(pin2ViewCenter, scaleAffineTransform)
pin2View.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, translatedPoint.x - pin2ViewCenter.x, translatedPoint.y - pin2ViewCenter.y)
}
func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView?, atScale scale: CGFloat) {
let scaleAffineTransform = CGAffineTransformScale(CGAffineTransformIdentity, scale, scale)
scrollView.contentSize = CGSizeApplyAffineTransform(self.imageView.bounds.size, scaleAffineTransform)
}
}

UIView doesn't center properly in UIScrollView with autolayout

I'm making an application where I need an x amount of custom UIView and place them in a scrollView. The layout of the scrollView and the UIView xib are set with AutoLayout. The result I'm getting now is this:
First View is well centred in ScrollView
Second View is wrong and has a lot of space in between
See my VC Code under here.
let sponsors = Sponsors.createSponsors() <-- Array
override func viewDidLoad() {
super.viewDidLoad()
configureSponsors()
}
//MARK: Load the AddView in ScrollView
func configureSponsors() {
self.scrollView.contentSize = CGSizeMake(CGFloat(sponsors.count) * self.scrollView.frame.size.width, self.scrollView.frame.size.height)
for sponsor in sponsors {
numberOfItems++
let addView = NSBundle.mainBundle().loadNibNamed("AddView", owner: self, options: nil).last as! AddView
addView.addDataToAddView(sponsor)
addView.frame = CGRectMake(CGFloat(numberOfItems - 1) * scrollView.frame.size.width, 0, scrollView.frame.size.width, scrollView.frame.size.height)
self.scrollView.addSubview(addView)
}
}
And here is my UIView code:
//MARK: Outlets
#IBOutlet weak var backgroundImageView: UIImageView!
#IBOutlet weak var sponsorTitle: UILabel!
#IBOutlet weak var sponsorLogo: UIImageView!
#IBOutlet weak var sponsorSubtitle: UILabel!
#IBOutlet weak var roundView: UIView!
#IBOutlet weak var playMusicButton: UIButton!
//MARK: Properties
var cornerRadius: CGFloat = 3.0
func addDataToAddView(sponsor: Sponsors) {
backgroundImageView.image = UIImage(named: sponsor.backgroundImage)
sponsorLogo.image = UIImage(named: sponsor.logoImage)
sponsorTitle.text = sponsor.title
sponsorSubtitle.text = sponsor.subTitle
}
override func layoutSubviews() {
roundView.layer.cornerRadius = roundView.frame.size.width / 2
roundView.alpha = 0.7
roundView.clipsToBounds = true
}
//MARK: PlayVideo
#IBAction func playVideo(sender: UIButton) {
//play music
}
I've already searched for the same problems. I found out that I have to use the Pure Auto Layout Approach. Should that mean I need to programatically set the constraints for the UIView?
Many thanks,
Dax
Update:
Pictures for scrollView setup:
You should not perform layout calculations in viewDidLoad as frames are not set correctly till then.
Correct place to do this is either viewWillLayoutSubviews or viewDidLayoutSubviews as you will get the correct frame data when these functions are called

ScrollView unable to display image which passed from another VC

I need to display the image pass in from the another ViewController
first,I have tested using only ImageView to display the image and it works as below:
Thanks. Your help is greatly appreciated.
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var TempImgView: UIImgeView!
var passInImg: UIImage?
override func viewDidLoad() {
super.viewDidLoad()
TempImgView.image = passInImg!
}
When I use UIScrollView ( for scrolling the large passInImg) , below code not working
Probelm:
error : fatal error: unexpectedly found nil while unwrapping an
optional value
But I have tested the pass in image in the above code.
what need to be done with the scrollView?
Should be used in viewDidLoad?
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var myUIScrollView: UIScrollView!
var myImgView: UIImageView!
var passInImg: UIImage?
override func viewDidLoad() {
super.viewDidLoad()
self.myUIScrollView.maximumZoomScale = 10.0
self.myUIScrollView.minimumZoomScale = 1.0
self.myUIScrollView.delegate = self
myImgView.image = passInImg!
self.myUIScrollView.addSubview(myImgView)
}
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return myImgView
}
First check if myUIScrollView is connected to an outlet in storyboard and always check before using an optional variable:
if let img = passInImg {
myImgView.image = img
}
The difference is the way you are declaring the UIImageView.
In the first case:
#IBOutlet weak var TempImgView: UIImageView!
TempImgView is an #IBOutlet and hence initialised whenever the storyboard view/xib is loaded.
But then when you are using the scrollview, you have declared the UIImageView as a class variable and not #IBOutlet.
var myImgView: UIImageView!
It has to initialised before you try to access it.
Try:
myImgView = UIImageView()
myImgView.image = passInImg!
Please initialize the myImgView with frame before set the image.
It return nil because the myImgView not initalize
myImgView = UIImageView(frame:CGRectMake(10, 50, 100, 300));
It works for me. Hope it will helps you.Thanks alot

Resources