I used two statements in my code when initializing newX variable which I believe they should give the same result but one didn't, which are:
( scrollView.frame.size.width / 2 ) - 75
And
scrollView.frame.midX - 75
here is my code, look for the comment at the middle:
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
var images = [UIImageView]()
var contentWidth: CGFloat = 0.0
override func viewDidAppear(_ animated: Bool) {
for i in 0...2 {
let image = UIImage(named: "icon\(i).png")
let imageView = UIImageView(image: image)
// Here is the problem
let newX = (scrollView.frame.size.width / 2 + scrollView.frame.size.width * CGFloat(i)) - 75
let newY = scrollView.frame.midY - 75
imageView.frame = CGRect(x: newX, y: newY, width: 150, height: 150)
scrollView.addSubview(imageView)
contentWidth += scrollView.frame.size.width
}
scrollView.contentSize = CGSize(width: contentWidth, height: view.frame.size.height)
scrollView.clipsToBounds = false
scrollView.backgroundColor = UIColor.purple
}}
The first one perfectly centred the images, but when I replaced it with the second on it didn't center them as shown in the picture here
Code Representation . why?
The difference is that midX is considering also the position of the scrollview's origin, so midX would be half the width of your scrollView + the X origin of your scrollView. (Similar to how minX is not always 0)
Width, on the other hand, is, well, the width of the scrollView, which is absolute.
Related
I'm learning to use UIScrollView to make several pictures could scroll horizontally. These images are programmatically added as a subview to a UIView within UIScrollView. The 'Scrolling enabled' is also set true. However, when I run the app, the UIScrollView cannot scroll.
Here is my code.
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var scrollContentView: UIView!
var imageViews = [UIImageView]()
override func viewDidLoad() {
super.viewDidLoad()
let imageWidth: CGFloat = 200.0 / 768.0 * 1024.0
for i in 1...3 {
let image = UIImage(named: "image\(i)")
let imageView = UIImageView(image: image)
imageViews.append(imageView)
let x: CGFloat = CGFloat(i - 1) * (imageWidth + 10)
scrollContentView.addSubview(imageView)
print(imageView.frame)
imageView.frame = CGRect(x: x, y: 0, width: imageWidth, height: 200.0)
}
scrollContentView.frame = CGRect(x: 0.0, y: 0.0, width: imageWidth * 3 + 20.0, height: 200.0)
scrollView.contentSize = scrollContentView.frame.size
}
}
Instead of creating the scrollContentView in Interface Builder, create it programmatically.
Xcode won't complain anymore about missing contraints, and you will be able to play with the frame manually.
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
var scrollContentView: UIView!
var imageViews = [UIImageView]()
override func viewDidLoad() {
super.viewDidLoad()
scrollContentView = UIView()
scrollView.addSubview(scrollContentView)
let imageWidth: CGFloat = 200.0 / 768.0 * 1024.0
for i in 1...3 {
let image = UIImage(named: "image\(i)")
let imageView = UIImageView(image: image)
imageViews.append(imageView)
let x: CGFloat = CGFloat(i - 1) * (imageWidth + 10)
scrollContentView.addSubview(imageView)
print(imageView.frame)
imageView.frame = CGRect(x: x, y: 0, width: imageWidth, height: 200.0)
}
scrollContentView.frame = CGRect(x: 0.0, y: 0.0, width: imageWidth * 3 + 20.0, height: 200.0)
scrollView.contentSize = scrollContentView.frame.size
}
}
Let say I have 3 images in the scroll view. Now I am able to scroll it horizontally in either way. However, when reached the image #3, how to allow it to continuous scroll to image #1.
override func viewDidAppear(_ animated: Bool) {
//allow scrolling even outside the scroll view
view.addGestureRecognizer(scrollView.panGestureRecognizer)
var contentWidth : CGFloat = 0.0
let scrollWidth = scrollView.frame.size.width
// append 3 images
for x in 0...2 {
let image = UIImage(named: "icon\(x).png")
let ImageView = (UIImageView(image:image))
images.append(ImageView)
var newX : CGFloat = 0.0
newX = scrollWidth/2 + scrollWidth * CGFloat(x)
scrollView.addSubview(ImageView)
//set the position of the image to center of the screen
ImageView.frame = CGRect(x: newX - 75, y: (scrollView.frame.size.height/2)-75, width: 150, height: 150)
contentWidth += newX
}
scrollView.clipsToBounds = false
scrollView.contentSize = CGSize(width: contentWidth, height: view.frame.size.height)
}
I have seen answers for this following question. I am new to swift programming and I am trying to implement a similar feature. I just wondered if you had any guidance on how to achieve this in swift 3 Xcode 8. I have been searching around for a suitable solution but I've had no luck.
I am trying use UIViews as a subview of UIscrollviews. I would also like to have each view fill the screen when pressed and shows another UIView. I have seen a similar feature on the GOLF app by 'Tyler the Creator'
The feature I am trying achieve is pictured below.
Any help you could give would be greatly appreciated.
This is a representation of the feature I am trying to create.
let scrollView : UIScrollView = UIScrollView(frame: CGRect(x: 80, y: 80,
width: 250, height: 300))
scrollView.isPagingEnabled = true
scrollView.backgroundColor = .orange
view.addSubview(scrollView)
let numberOfPages :Int = 5
let padding : CGFloat = 15
let viewWidth = scrollView.frame.size.width - 2 * padding
let viewHeight = scrollView.frame.size.height - 2 * padding
var x : CGFloat = 0
for i in 0...numberOfPages{
let view: UIView = UIView(frame: CGRect(x: x + padding, y: padding, width: viewWidth, height: viewHeight))
view.backgroundColor = UIColor.white
scrollView .addSubview(view)
x = view.frame.origin.x + viewWidth + padding
}
scrollView.contentSize = CGSize(width:x+padding, height:scrollView.frame.size.height)
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
var colors:[UIColor] = [.red, .blue, .green, .yellow]
var frame: CGRect = CGRect(x: 0, y: 0, width: 0, height: 0)
override func viewDidLoad() {
super.viewDidLoad()
scrollView.isPagingEnabled = true
scrollView.backgroundColor = .orange
view.addSubview(scrollView)
let numberOfPages :Int = 3
let padding : CGFloat = 15
let viewWidth = scrollView.frame.size.width - 2 * padding
let viewHeight = scrollView.frame.size.height - 2 * padding
var x : CGFloat = 0
for i in 0...numberOfPages{
let view: UIView = UIView(frame: CGRect(x: x + padding, y: padding, width: viewWidth, height: viewHeight))
view.backgroundColor = colors[i]
scrollView .addSubview(view)
x = view.frame.origin.x + viewWidth + padding
}
scrollView.contentSize = CGSize(width:x+padding, height:scrollView.frame.size.height)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You should use UIPageViewController. That class is exactly meant to do what you are looking for with ease.
See UIPageViewController
You can embed your UIPageViewController in a UIContainerView to fit it anywhere.
I am trying to align my images vertical in my scrollView. Unfortunately I can't figure out what the problem is. I think it's something mathematical and this is not my strongest thing. :(
I hope someone can help me out with this problem. I will also provide my code and image of the problem below:
//
// muscleListVC.swift
// ActiveRest
//
// Created by Fhict on 04/10/16.
// Copyright © 2016 Kevin Vugts. All rights reserved.
//
import UIKit
class muscleListVC: UIViewController {
var images = [UIImageView]()
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
print("Count: \(images.count)")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
var contentHeight: CGFloat = 0.0
let scrollHeight = scrollView.frame.size.height
for x in 0...4 {
let image = UIImage(named: "muscle\(x).png")
let imageView = UIImageView(image: image)
images.append(imageView)
var newX: CGFloat = 0.0
newX = scrollHeight / 4 + scrollHeight * CGFloat(x) / 4
print("the size is \(newX)")
contentHeight += newX
scrollView.addSubview(imageView)
imageView.frame = CGRect(x: 0, y: newX, width: view.frame.size.width, height: 166)
print("the content height: \(contentHeight)")
scrollView.contentSize = CGSize(width: scrollView.frame.size.width, height: contentHeight)
}
scrollView.clipsToBounds = false
}
}
Thank you very much! <3
I am not quite sure what you intend to do but I tried to modify your code a bit to make it work.
override func viewDidLoad() {
super.viewDidLoad()
let numberOfImages = 5
let imageViewHeight:CGFloat = 166.0
scrollView.contentSize = CGSize(width: view.frame.size.width, height: imageViewHeight*(CGFloat)(numberOfImages))
var newY:CGFloat = 0
for x in 0...(numberOfImages-1) {
let image = UIImage(named: "muscle\(x).png")
let imageView = UIImageView(image: image)
images.append(imageView)
imageView.frame = CGRect(x: 0, y: newY, width: view.frame.size.width, height: imageViewHeight)
newY = newY + CGFloat(imageViewHeight)
scrollView.addSubview(imageView)
}
}
I have a scrollView containing a single image. The image's bounds are greater than the scrollView's frame. I have set the scrollView's contentSize to be equal to the image's bounds.
Yet no scrolling. I have no idea what could be causing this.
override func viewDidLoad() {
super.viewDidLoad()
var matches = SortThread.getSortThread().retrieveMatches()
scrollView.frame = CGRectMake(0, navigationController!.navigationBar.frame.height - 20, UIScreen.mainScreen().bounds.width, view.bounds.height - (navigationController!.navigationBar.frame.height - 20))
var imageName = String()
imageName = matches[0].pictures![0]
var parsedImageName = imageName.componentsSeparatedByString(".") as [String]
var newImageName: String = parsedImageName[0] as String
let path = NSBundle.mainBundle().pathForResource("MVLMP Images (Resized)/" + newImageName, ofType: "jpg")
var image = UIImage()
image = UIImage(contentsOfFile: path!)!
var imageView = UIImageView(image: image)
var ratio: CGFloat = image.size.width/image.size.height
var screenHeight: CGFloat = UIScreen.mainScreen().bounds.height - navigationController!.navigationBar.frame.height - 20
if(ratio > 1){
imageView.frame = CGRectMake(0, 0, ((scrollView.bounds.width)/7) * 6, 0)
imageView.frame = CGRectMake(0, 0, imageView.frame.width, imageView.frame.width * ratio)
} else {
imageView.frame = CGRectMake(0, 0, 0, (screenHeight/9)*8)
imageView.frame = CGRectMake(0, 0, imageView.frame.height * ratio, imageView.frame.height)
}
scrollView.addSubview(imageView)
scrollView.contentSize.width = imageView.frame.width
scrollView.contentSize.height = imageView.frame.height
}
}
I've printed out the scrollView.contentSize.width and the scrollView.bounds.width and the content width is in fact greater than the bounds width by about 40.
As Muc Dong commented, I was adding the width of the images to the scrollView's contentSize.width. This was not necessarily the correct thing to do as in my case there is some margin between the images that I was not accounting for. This margin should of been included in the additions to to scrollView.contentSize.width.