Cannot set UIScrollView contentSize based on UIIMage - ios

I am struggling for 2 hours now to get a UIScrollView.contentSize with the size of a UIImage, but the UIImage doesn't return a proper size, I have no idea why.
The result is that my scrollView content is square(the same as the scrollView's frame) and I can't scroll to the side of the image.
This is really frustrating! You can see in the debugger that my image1.size is invalid.

you are accessing an image from array which doesn't exist see your console log it's clearly saying index out of range. that's why your not getting any size and height as well because there's no image in the specific index

Your image view size is showing wrong because your scrollview content size is wrong. Use this method than print your image view frame. It will work
override func viewDidLayoutSubviews()
{
self.scrollView1.delegate = self
self.scrollView1.contentSize = CGSize(width:self.view.frame.size.width, height: self.view.frame.size.height)
}

OK, I have been struggling with this for a while now, and finally I was able to find the answer. The problem was indeed in the content size, and I was finally able to calculate it correctly as below:
let tempScrollView = UIScrollView(frame: self.imageLocationsArray[imageID])
let tempImageView = UIImageView(image: image)
//determine proportions of image against frame
let imageWidthFactor = image.size.width / tempScrollView.frame.width
let imageHeightFactor = image.size.height / tempScrollView.frame.height
//image is too wide
if imageWidthFactor > imageHeightFactor {
tempImageView.frame = CGRect(x: 0, y: 0, width: tempScrollView.frame.width * imageWidthFactor / imageHeightFactor, height: tempScrollView.frame.height)
}
//image is too tall
else {
tempImageView.frame = CGRect(x: 0, y: 0, width: tempScrollView.frame.width, height: tempScrollView.frame.height * imageHeightFactor / imageWidthFactor)
}

Related

UIImageView frame not placing correctly on the parent ImageView

I have a color palette imageview, in that I want to place a plus icon(imageView) according to the x and y-axis I am getting from the backend. If I get x = 0 and y = 0 the frame of the plus is placing correctly
For y axis if I set height of the color palette imageView to the plus icon's frame's y axis, the icon is not going to the actual (0,0)
.
The code I used is below
let cWidth = self.colorPalleteImageView.frame.size.width // 348
let cHeight = self.colorPalleteImageView.frame.size.height // 378.5
let imageView = UIImageView(image: appImages.roundPlusIcon.image)
imageView.frame = CGRect(x: 0, y: cHeight, width: 22, height: 22)
colorPalleteImageView.addSubview(imageView)
I am checking this with iPad 12.9 inch simulator. Am I missing anything to achieve that x=0 and y=0, If I give the width of the colorPaletteImage to the x-axis of plusIconImageView it is not going to end fo the x-axis, It stays before the end of the width of the imageview, I don't know why it is happening, Need help
You're using frame sizes before the frames are finished being set by auto-layout.
I'd suggest using constraints, but if you want to stick to frame coordinates...
add the "round plus" icon imageView in viewDidLoad()
set its frame.origin in viewDidLayoutSubviews() or viewDidAppear()
imageView.frame = CGRect(x: cWidth, y: cHeight, width: 22, height: 22)
mast be:
imageView.frame = CGRect(x: 0, y: 0, width: 22, height: 22)
as axes are:
0,0-----------------> x
| ▢
|
|
|
V
with 0,0 you put top left of little image to to top left of big.
You can fix this issue by modifying the height property to the super view's bound's height. You need to know the difference between frame and bounds to understand why this is happening. In simple words frame is the CGRect with respect to it's super view and bounds is the CGRect with respect to it's own coordinates.
Plenty of detailed explanations are available online just need to google frame vs bounds and you'll get used to both of these after you play with it many times.
Here's how you fix this issue.
let cHeight = self.colorPalleteImageView.bounds.size.height
sorry.. I am back
I did (to follow your code I forced values..)
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var colorPalleteImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let v = self.view
print(v!.frame)
let cHeight = CGFloat(378.5)
colorPalleteImageView.frame.size.width = 348
colorPalleteImageView.frame.size.height = cHeight
let plusImg = UIImage(named: "plus")
let imageView = UIImageView(image: plusImg)
imageView.frame = CGRect(x: 0, y: cHeight-22, width: 22, height: 22)
colorPalleteImageView.addSubview(imageView)
}
}
and I got: (on iPad)

How to make a UIImageView have a square size based on a given bounds/container

So I am trying to create a simple UIImageView to make it have a square frame/size with CGSize. Based on a given bounds. So for example if the bounds container is the width & height of the screen then. The function should resize the UIImageView to fit like a perfect square base on those bounds on the screen.
Code:
let myImageView = UIImageView()
myImageView.frame.origin.y = (self.view?.frame.height)! * 0.0
myImageView.frame.origin.x = (self.view?.frame.width)! * 0.0
myImageView.backgroundColor = UIColor.blue
self.view?.insertSubview(myImageView, at: 0)
//("self.view" is the ViewController view that is the same size as the devices screen)
MakeSquare(view: myImageView, boundsOf: self.view)
func MakeSquare(view passedview: UIImageView, boundsOf container: UIView) {
let ratio = container.frame.size.width / container.frame.size.height
if container.frame.width > container.frame.height {
let newHeight = container.frame.width / ratio
passedview.frame.size = CGSize(width: container.frame.width, height: newHeight)
} else{
let newWidth = container.frame.height * ratio
passedview.frame.size = CGSize(width: newWidth, height: container.frame.height)
}
}
The problem is its giving me back the same bounds/size of the container & not changed
Note: I really have know idea how to pull this off, but wanted to see if its possible. My function comes from a question here. That takes a UIImage and resizes its parent view to make the picture square.
This should do it (and will centre the image view in the containing view):
func makeSquare(view passedView: UIImageView, boundsOf container: UIView) {
let minSize = min(container.bounds.maxX, container.bounds.maxY)
passedView.bounds = CGRect(x: container.bounds.midX - minSize / 2.0,
y: container.bounds.midY - minSize / 2.0,
width: minSize, height: minSize)
}

Alignment of UIImageView within UIScrollView

I see this topic in quite a few places but I can't figure out why exactly my code doesn't work.
I have an image of an artificial horizon that goes from -90 to 90 degrees. I want to view it through a small window which just shows around -20 to 20 degrees. Then I want to move the image up and down based on the angle my robot is leaning.
I started by adding a UIImage to a UIImageView. All of the alignment is correct. Then I thought the easiest way to move the image up and down was to add the UIImageView to a UIScrollView. Now I can't figure out how to get the alignment right. I see the image in there if I drag in the scrollview but as soon as I let go it goes back to where it was.
Here is the code I have. This is the first Swift code I have written so if there is a better way to do this I welcome any ridicule (just kidding, be gentle)
override func viewDidLoad() {
super.viewDidLoad()
let imageRect = CGRectMake(self.view.frame.width / 2 - 100, self.view.frame.height / 2, 200, 200)
self.myImageView = UIImageView.init()
self.myImageView = UIImageView(frame: imageRect)
self.myImageView.contentMode = UIViewContentMode.Center
self.myImageView.clipsToBounds = true
self.myImageView.image = UIImage.init(named:"horizon")
//self.view.addSubview(self.image)
self.myScrollView = UIScrollView(frame: imageRect)
self.myScrollView.contentSize = CGSize(width: imageRect.width, height: imageRect.height)
self.myImageView.center = self.myScrollView.center
self.myScrollView.frame = imageRect
self.myScrollView.backgroundColor = UIColor.blackColor()
self.myScrollView.contentOffset = CGPoint(x: 0, y: 0)
self.myScrollView.addSubview(self.myImageView)
self.view.addSubview(self.myScrollView)
/////////
self.connectionStatusLabel.text = "Disconnected"
self.connectionStatusLabel.textColor = UIColor.redColor()
self.textBox.font = UIFont(name: self.textBox.font!.fontName, size: 8)
// Watch Bluetooth connection
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.connectionChanged(_:)), name: BLEServiceChangedStatusNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.dataReceived(_:)), name: BLEDataChangedStatusNotification, object: nil)
// Start the Bluetooth discovery process
btDiscoverySharedInstance
}
You have to set the scrollView's contentSize to the actual image size not the imageView's size. And set the imageView's size to the actual image size as well:
let image = UIImage.init(named:"horizon")
// Set the imageView's size to the actual image size
self.myImageView.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
...
...
// Set the scrollView's contentSize to the actual image size
self.myScrollView.contentSize = image.size

Swift / cut background image

My background image is set with UIView extension.
extension UIView {
func addBackground() {
// screen width and height:
let width = UIScreen.mainScreen().bounds.size.width
let height = UIScreen.mainScreen().bounds.size.height
let imageViewBackground = UIImageView(frame: CGRectMake(0, 0, width, height))
imageViewBackground.image = UIImage(named: "index_clear")
// you can change the content mode:
imageViewBackground.contentMode = UIViewContentMode.ScaleAspectFill
self.addSubview(imageViewBackground)
self.sendSubviewToBack(imageViewBackground)
}}
For segue animation the view moves from left to right. The background image is way larger than the screen, what is visible while the animation.
How can I cut the background image to perfectly fit into the view?
.ScaleAspectFit does the job, but since it's a picture it looks bad.
Help is very appreciated.
You can use .ScaleAspectFill to crop the image rather than scale it to fit. This won't distort your image, but obviously you won't be able to see the whole thing.
You need to ensure that you set clipsToBounds=true on the UIImageView so that the cropped area isn't visible
extension UIView {
func addBackground() {
// screen width and height:
let width = UIScreen.mainScreen().bounds.size.width
let height = UIScreen.mainScreen().bounds.size.height
let imageViewBackground = UIImageView(frame: CGRectMake(0, 0, width, height))
imageViewBackground.image = UIImage(named: "index_clear")
// you can change the content mode:
imageViewBackground.contentMode = UIViewContentMode.ScaleAspectFill
imageViewBackground.clipsToBounds=true
self.addSubview(imageViewBackground)
self.sendSubviewToBack(imageViewBackground)
}

Setting large images in UIScrollView

I want to put images in UIScrollView. However, the problem is that when I try to put an image larger than UIScrollView, UIScrollView shows the upper part of images. I would like the scrollview to show the bottom part of the image. Right now, I have the following code:
let imgBot1 = UIImage(named:"Img1.jpg");
let imgBot2 = UIImage(named:"Img4.jpg");
let imgBot3 = UIImage(named:"Img5.jpg");
//Adding UIImage in UIImageView
let imgView1 = UIImageView(image:imgBot1)
let imgView2 = UIImageView(image:imgBot2)
let imgView3 = UIImageView(image:imgBot3)
//creating UIScrollView
let scrView2 = UIScrollView()
scrView2.frame = CGRectMake(0, self.view.frame.height/2,
self.view.frame.width, self.view.frame.height)
//content size of the scrollview
scrView2.contentSize = CGSizeMake(self.view.frame.width*3, self.view.frame.height)
//Size and place of UIImageView
imgView1.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
imgView2.frame = CGRectMake(width, 0, self.view.frame.width, self.view.frame.height)
imgView3.frame = CGRectMake(width*2, 0, self.view.frame.width, self.view.frame.height)
//adding the scrollview to the view
self.view.addSubview(scrView2)
scrView2.addSubview(imgView1)
scrView2.addSubview(imgView2)
scrView2.addSubview(imgView3)
scrView2.pagingEnabled = true
//Initial location of the scrollview
scrView2.contentOffset = CGPointMake(0, 0);
I would like to know how I can make the scrollview to show the bottom part of the image, and not the top part. Will you help me out?
I made this code, hope it will work for you. I used the storyboard, made a scrollView, added an imageView and added constrains to the image view to stick to the edges (don't know it that's necessary).
imageView = UIImage(named: "image")
scrollView.contentOffset = CGPoint(x: 0, y: image.image!.size.height)

Resources