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)
}
}
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
}
}
I have a UIScrollView with paging enabled. All works good but sometimes when I scroll to the next image, 1 pixel from the last image is still displayed.
as you can see on the very left of the image, there is 1 pixel vertical line that is from the image before it. Meaning that the image was not swiped completely.
I tried a lot but couldn't find the problem.
Here is my code:
import Foundation
import UIKit
import SwiftyGif
class MBSPagingScrollView: UIScrollView, UIScrollViewDelegate {
var scrollView = UIScrollView()
var pageControl = UIPageControl()
var imagesArray = [String]()
override init (frame : CGRect) {
super.init(frame : frame)
}
convenience init () {
self.init(frame:CGRect.zero)
}
required init(coder aDecoder: NSCoder) {
fatalError("This class does not support NSCoding")
}
init(frame : CGRect, imagesarray : [String]){
super.init(frame : frame)
imagesArray = imagesarray
scrollView.delegate = self
scrollView.isPagingEnabled = true
scrollView.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)
scrollView.showsHorizontalScrollIndicator = false
self.addSubview(scrollView)
pageControl.frame = CGRect(x: 0, y: self.frame.size.height - 50, width: self.frame.size.width, height: 50)
pageControl.numberOfPages = imagesArray.count
pageControl.currentPage = 0
pageControl.tintColor = UIColor.red
pageControl.pageIndicatorTintColor = UIColor.black
pageControl.currentPageIndicatorTintColor = MainOrangeColor
self.addSubview(pageControl)
scrollView.contentSize = CGSize(width:scrollView.frame.size.width * CGFloat(imagesArray.count),height: scrollView.frame.size.height)
pageControl.addTarget(self, action: #selector(changePage(sender:)), for: UIControlEvents.valueChanged)
for (index, imageName) in imagesArray.enumerated() {
var imageView = UIImageView()
if imageName.hasSuffix(".gif") {
let gifManager = SwiftyGifManager(memoryLimit:30)
let gif = UIImage(gifName: imageName)
imageView = UIImageView(gifImage: gif, manager: gifManager)
}
else {
imageView = UIImageView(image: UIImage(named: imageName))
imageView.contentMode = UIViewContentMode.scaleToFill
}
imageView.frame = CGRect(x: CGFloat(index) * self.frame.size.width, y: 0, width: self.frame.size.width, height: self.frame.size.height)
scrollView.addSubview(imageView)
}
}
func changePage(sender: AnyObject) -> () {
let x = CGFloat(pageControl.currentPage) * scrollView.frame.size.width
scrollView.setContentOffset(CGPoint(x:x, y:0), animated: true)
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
pageControl.currentPage = Int(pageNumber)
}
}
Any help is much appreciated.
Thanks a lot!
Try and set clipsToBounds = true for all the imageviews.
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 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.
I create a new UIViewController, I don't use storyboard, this is my code. I want to change my view frame, this not work for me, I had try to add on viewWillAppear, it's still not work, I know I can add a new UIView to do it. Can I change my viewcontroller's view? Thanks your help.
import UIKit
class NewDetailViewController: UIViewController {
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
let statusBarHeight: CGFloat = UIApplication.sharedApplication().statusBarFrame.height
let navBarHeight = self.navigationController?.navigationBar.frame.size.height
println("statusBarHeight: \(statusBarHeight) navBarHeight: \(navBarHeight)")
// view
var x:CGFloat = self.view.bounds.origin.x
var y:CGFloat = self.view.bounds.origin.y + statusBarHeight + CGFloat(navBarHeight!)
var width:CGFloat = self.view.bounds.width
var height:CGFloat = self.view.bounds.height - statusBarHeight - CGFloat(navBarHeight!)
var frame:CGRect = CGRect(x: x, y: y, width: width, height: 100)
println("x: \(x) y: \(y) width: \(width) height: \(height)")
self.view.frame = frame
self.view.backgroundColor = UIColor.redColor()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
I found I add on viewDidLayoutSubviews, it work for me.
override func viewDidLayoutSubviews() {
let statusBarHeight: CGFloat = UIApplication.sharedApplication().statusBarFrame.height
let navBarHeight = self.navigationController?.navigationBar.frame.size.height
println("statusBarHeight: \(statusBarHeight) navBarHeight: \(navBarHeight)")
// view
var x:CGFloat = self.view.bounds.origin.x
var y:CGFloat = self.view.bounds.origin.y + statusBarHeight + CGFloat(navBarHeight!)
var width:CGFloat = self.view.bounds.width
var height:CGFloat = self.view.bounds.height - statusBarHeight - CGFloat(navBarHeight!)
var frame:CGRect = CGRect(x: x, y: y, width: width, height: height)
println("x: \(x) y: \(y) width: \(width) height: \(height)")
self.view.frame = frame
self.view.backgroundColor = UIColor.redColor()
}