I am trying to make a page control associated with an image array. I had it setup correctly just changing the background color and load in the initial image, but when I scroll nothing further is shown. Here is my code:
var images: [UIImage] = [
UIImage(named: "slide1.png")!,
UIImage(named: "loginButton.png")!,
UIImage(named: "slide1.png")!,
UIImage(named: "slide1.png")!
]
func setPageViewinScroll() {
for index in 0..<4 {
frame.origin.x = self.scrollView.frame.size.width * CGFloat(index)
frame.size = self.scrollView.frame.size
self.scrollView.pagingEnabled = true
self.imageView.image = images[index]
let subview = UIView(frame: frame)
self.scrollView.addSubview(subview)
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * 4, self.scrollView.frame.size.height)
pageControl.addTarget(self, action: Selector("changePage:"), forControlEvents: UIControlEvents.ValueChanged)
}
func changePage(sender: AnyObject) -> () {
let x = CGFloat(pageControl.currentPage) * scrollView.frame.size.width
scrollView.setContentOffset(CGPointMake(x, 0), animated: true)
}
Does anyone know where I am going wrong here?
How about adding your UIImageview to UIScrollview instead of UIView like this code?
var imageOne:UIImageView!
var imageTwo:UIImageView!
var imageThree:UIImageView!
var imageFour:UIImageView!
func functionCalledFromViewDidLoad() {
scrollView.frame = CGRectMake(0, 0, self.view.frame.width,self.view.frame.height)
let scrollViewWidth = scrollView.frame.width
let scrollViewHeight = scrollView.frame.height
imageOne = UIImageView(frame: CGRectMake(0, 0,scrollViewWidth, scrollViewHeight))
imageTwo = UIImageView(frame: CGRectMake(scrollViewWidth*1, 0,scrollViewWidth, scrollViewHeight))
imageThree = UIImageView(frame: CGRectMake(scrollViewWidth*2, 0,scrollViewWidth, scrollViewHeight))
imageFour = UIImageView(frame: CGRectMake(scrollViewWidth*3, 0,scrollViewWidth, scrollViewHeight))
scrollView.addSubview(imageOne)
scrollView.addSubview(imageTwo)
scrollView.addSubview(imageThree)
scrollView.addSubview(imageFour)
}
override func viewDidLayoutSubviews() {
scrollView.contentSize = CGSizeMake(scrollView.frame.width * 4, scrollView.frame.height)
imageOne.frame.size.height = scrollView.frame.height
imageTwo.frame.size.height = scrollView.frame.height
imageThree.frame.size.height = scrollView.frame.height
imageFour.frame.size.height = scrollView.frame.height
}
You also seem to need to add this code.
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
// Test the offset and calculate the current page after scrolling ends
let pageWidth:CGFloat = CGRectGetWidth(scrollView.frame)
let currentPage = Int(floor((scrollView.contentOffset.x-pageWidth/2)/pageWidth)+1)
// Change the page indicator
self.pageControl.currentPage = Int(currentPage)
}
There is a very good tutorial related to this topic, here
You are setting the image on the imageView and not on the subView. I.o.w. You are adding the subview to each page, but not setting the image on it.
Change the subview code to the following
let subview = UIImageView(frame: frame)
subview.image = images[index]
self.scrollView.addSubview(subview)
Related
I'm trying to zoom an image that is inside a UIScrollView, and that UIScrollView it's inside of a root UIScrollView that allow paging, similar to the Photos app.
In the viewDidLoad() inside the view that contains the root scrollView I call prepareScrollView()
func prepareScrollView(){
let tap = UITapGestureRecognizer(target: self, action: #selector(hideNavigationItem))
scrollView.addGestureRecognizer(tap)
scrollView.delegate = self
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 4.0
scrollView.zoomScale = 1.0
let width = self.view.bounds.width
let height = self.view.bounds.height
totalWidth = width * CGFloat((imageArray!.count)!) //The width must be the width of the screen by the number of the images in the array
scrollView.contentSize = CGSize(width: totalWidth, height: height)
scrollView.isPagingEnabled = true
loadPages()
}
The loadPages() function load every scrollView with their image and add it to the root scrollview.
func loadPages(){
for i in 0...((imageArray!.count)! - 1){
let pageScroll = Page(frame: CGRect(x: self.view.bounds.size.width * CGFloat(i), y: self.view.frame.origin.y, width: self.view.bounds.size.width, height: self.view.bounds.size.height))
pageScroll.minimumZoomScale = 1.0
pageScroll.maximumZoomScale = 4.0
pageScroll.zoomScale = 1.0
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height))
imageView.image = UIImage(data: (imageArray![i])!)
imageView.contentMode = .scaleToFill
pageScroll.addSubview(imageView)
scrollView.addSubview(pageScroll)
}
}
The Page object it's just a UIScrollView object.
class Page: UIScrollView {
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return self.subviews[0]//Return the image
}
}
And inside the root scrollView viewForZooming function it calls the viewForZooming function of the correspond child scrollview.
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
if(self.scrollView.subviews.count > 0){
let childScrollView = self.scrollView.subviews[currentPage] as! Page
let image = childScrollView.viewForZooming(in: scrollView)
return image
}
return nil
}
With this approach I can navigate horizontally but I can't zoom in the current image. The viewForZooming function executes in both objects. What I'm doing wrong?
Finally I solve my issue. I changed the Page object to a simple UIScrollView and then set the delegate of the scrollView object to self.
func loadPages(){
for i in 0...((comic?.comicsPages!.count)! - 1){
let pageScroll = UIScrollView(frame: CGRect(x: self.view.bounds.size.width * CGFloat(i), y: self.view.frame.origin.y, width: self.view.bounds.size.width, height: self.view.bounds.size.height))
pageScroll.minimumZoomScale = 1.0
pageScroll.maximumZoomScale = 4.0
pageScroll.zoomScale = 1.0
pageScroll.isUserInteractionEnabled = true
pageScroll.delegate = self //Here
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height))
imageView.image = UIImage(data: (imageArray![i])!)
imageView.contentMode = .scaleToFill
pageScroll.addSubview(imageView)
scrollView.addSubview(pageScroll)
}
}
And then in the viewForZooming function of the root scrollView I change the code for this:
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
if(scrollView.subviews.count > 0){
return scrollView.subviews[0]
}
return nil
}
The scrollView parameter is the child scrollview so it works as expected.
I am trying to learn the basics of IOS development and Ive been experimenting with different views.
I tried to make a scroll view that display an array of images which scrolls properly but none of the images appear?
import UIKit
class ViewController: UIViewController {
var imagesArray = [UIImage]()
let scrollView: UIScrollView = {
let scroll = UIScrollView()
scroll.isPagingEnabled = true
scroll.showsVerticalScrollIndicator = false
scroll.showsHorizontalScrollIndicator = false
scroll.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
return scroll
}()
override func viewDidLoad() {
super.viewDidLoad()
setScrollView()
}
func setScrollView(){
self.view.addSubview(scrollView)
imagesArray = [UIImage(named:"gamerrr"),UIImage(named:"family"),UIImage(named:"gamerrr"),UIImage(named:"family"),UIImage(named:"family")] as! [UIImage]
setUpImages(imagesArray)
}
func setUpImages(_ images:[UIImage]){
for i in 0..<images.count {
// container of each image
let imageView = UIImageView()
// shifting to next image
let xPos = UIScreen.main.bounds.width * CGFloat(i)
// width and height of the screen
imageView.frame = CGRect(x: xPos, y: 0, width: scrollView.frame.width, height: scrollView.frame.height)
imageView.contentMode = .scaleAspectFit
// shifting to next image
scrollView.contentSize.width = scrollView.frame.width * CGFloat(i+1)
scrollView.addSubview(imageView)
}
}
}
You may need to set the image
let imageView = UIImageView(image:images[i])
I want horizontal scrollview with image view but image is not fitting with the scroll. i am doing this code but not getting the right thing
Here is my code
#IBOutlet weak var upperScroll: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.isHidden = true
// Do any additional setup after loading the view.
var logoImage: [UIImage] = [
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
]
upperScroll.isScrollEnabled = true
let scrollWidth: Int = Int(self.view.frame.width)
upperScroll.contentSize = CGSize(width: CGFloat(scrollWidth), height:(self.upperScroll.frame.height))
upperScroll.frame = CGRect(x: 0, y: 51, width: upperScroll.frame.size.width, height: self.upperScroll.frame.height)
upperScroll.backgroundColor = UIColor.red
var xOffset: Int = 0
for index in 0..<logoImage.count {
let img = UIImageView(frame: CGRect(x: CGFloat(xOffset), y: 0, width: upperScroll.frame.size.width, height: self.upperScroll.frame.height))
img.image = logoImage[index]
upperScroll.addSubview(img)
xOffset += 100
}
view.addSubview(upperScroll)
upperScroll.contentSize = CGSize(width: CGFloat((scrollWidth + xOffset)), height: 110)
}
but i want this
Can anyone please help me? Thanks
Just remove your appdelegate code and add my fuction
also set scrollview constraint like leading,trailing,top,bottom Zero
func scrollImage() {
super.viewDidLoad()
self.navigationController?.navigationBar.isHidden = true
// Do any additional setup after loading the view.
var logoImage: [UIImage] = [
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!,
UIImage(named: "slider.png")!]
upperScroll.isPagingEnabled = true
upperScroll.isScrollEnabled = true
let scrollWidth: Int = Int(self.view.frame.width)
,
upperScroll.contentSize = CGSize(width: CGFloat(scrollWidth), height:(self.upperScroll.frame.height))
print(upperScroll.frame.size.width)
upperScroll.backgroundColor = UIColor.red
for index in 0..<logoImage.count {
let xPosition = self.view.frame.width * CGFloat(index)
upperScroll.layoutIfNeeded()
let img = UIImageView(frame: CGRect(x: CGFloat(xPosition), y: 0, width: upperScroll.frame.size.width, height: self.upperScroll.frame.height))
img.layoutIfNeeded()
img.image = logoImage[index]
upperScroll.addSubview(img)
}
view.addSubview(upperScroll)
upperScroll.contentSize = CGSize(width: CGFloat((scrollWidth) * logoImage.count), height: self.upperScroll.frame.height)
}
I hope it's save your time and working great
According to your requirement, the xOffset += 100 should be changed to xOffset += scrollWidth. And contents size set to:
upperScroll.contentSize = CGSize(width: CGFloat((scrollWidth * logoImage.count)), height: 110)
And remember to enable the pagination for scroll view.
First of all, you need two outlet for scroll view and PageControl,
var contentWidth:CGFloat = 0.0
// MARK: - Welcome screen with scroll view use page controll
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
scrollView.delegate = self
let myImages = ["intro1_1.png", "intro2_2.png", "intro3_3.png"] // images which loaded in assets
let imageWidth:CGFloat = view.frame.width
let imageHeight:CGFloat = view.frame.height
var xPosition:CGFloat = 0 //setup your position
var scrollViewSize:CGFloat=0 //setup your position
for image in myImages {
let myImage:UIImage = UIImage(named: image)!
let myImageView:UIImageView = UIImageView()
myImageView.image = myImage
myImageView.frame.size.width = imageWidth
myImageView.frame.size.height = imageHeight
myImageView.frame.origin.x = xPosition
myImageView.frame.origin.y = 0
scrollView.addSubview(myImageView)
xPosition += imageWidth
scrollViewSize += imageWidth
}
scrollView.contentSize = CGSize(width: scrollViewSize, height: imageHeight)
scrollView.contentSize = CGSize(width: view.frame.width * 3, height: view.frame.height) //here you setup how many pages in scroll will
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageWidth:CGFloat = scrollView.frame.width
let currentPage:CGFloat = floor((scrollView.contentOffset.x-pageWidth / 2)/pageWidth)+1
self.pageControll.currentPage = Int(currentPage)
}
hope, i help u
Swift(iOS) problem: how can I insert UIImage array to subview? I wanted to make a horizontal scroll view in view controller with very little experience with swift. Here is the code:
override func viewDidLoad() {
super.viewDidLoad()
configurePageControl()
var pictures:[UIImage] = [ ]
pictures.append(UIImage(named: "SOVERMENT1.jpg")!)
pictures.append(UIImage(named: "SOVERMENT2.jpg")!)
pictures.append(UIImage(named: "SOVERMENT3.jpg")!)
pictures.append(UIImage(named: "SOVERMENT4.jpg")!)
scrollView.delegate = self
self.view.addSubview(scrollView)
for index in 0..<4 {
frame.origin.x = self.scrollView.frame.size.width * CGFloat(index)
frame.size = self.scrollView.frame.size
self.scrollView.pagingEnabled = true
var subView = UIView(frame: frame)
**subView.backgroundColor = [UIColor colorWithPatternImage : ]**
self.scrollView.addSubview(subView)
}
This is first problem. How can I insert pictures into subview.backgroundColor? I searched it for 1~2hours, but I couldn't find any answer.
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * 4, self.scrollView.frame.size.height)
pageControl.addTarget(self, action: Selector("changePage:"), forControlEvents: UIControlEvents.ValueChanged)
}
func configurePageControl() {
** self.pageControl.numberOfPages = pictures.count **
self.pageControl.currentPage = 0
And here. Why array pictures cannot be counted?
Unless these are repeatable pattern images, I think you want to use a UIImageView. I also don't think you need to use a UIPageControl, because you're only using one UIViewController. You can say something like:
override func viewDidLoad() {
super.viewDidLoad()
var pictures:[UIImage] = [ ]
pictures.append(UIImage(named: "SOVERMENT1.jpg")!)
pictures.append(UIImage(named: "SOVERMENT2.jpg")!)
pictures.append(UIImage(named: "SOVERMENT3.jpg")!)
pictures.append(UIImage(named: "SOVERMENT4.jpg")!)
self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * CGFloat(pictures.count), scrollView.frame.size.height)
for index in 0..<pictures.count {
var frame = CGRectZero
frame.origin.x = scrollView.frame.size.width * CGFloat(index)
frame.size = scrollView.frame.size
scrollView.pagingEnabled = true
var subView = UIImageView(frame: frame)
subView.image = pictures[index]
subView.contentMode = .ScaleAspectFit
self.scrollView.addSubview(subView)
}
}
You better use UICollectionView for such purposes
For setting the backgroundColor call the UIColor initializer:
for picture in pictures {
subView.backgroundColor = UIColor(patternImage: picture)
}
I am trying to make an infinite loop image gallery app. I did it by setting up a UIScrollView inside which I inserted UIImageViews.
I am able to load 4 images and swipe between them, but the problem I have is how to implement the infinite scroll, so that after the last image, the first one appears and opposite.
As I am newbie in Swift, I don't know how to handle this problem nor where to start. I will appreciate any suggestion, example or link on how to solve this problem.
Thanks in advance!
Here is the peace of my code:
class FirstViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
self.scrollView.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
let scrollViewWidth: CGFloat = self.scrollView.frame.width
let scrollViewHeight: CGFloat = self.scrollView.frame.height
let numPics: Int = 3
let imgOne = UIImageView()
let imgTwo = UIImageView()
let imgThree = UIImageView()
let imgFour = UIImageView()
var arrPics = [imgOne, imgTwo, imgThree, imgFour]
var arrSlide = ["slide1.png", "slide2.png", "slide3.png", "slide4.png"]
for i in 0...numPics {
arrPics[i] = UIImageView(frame: CGRectMake(0,scrollViewHeight * CGFloat(i),scrollViewWidth, scrollViewHeight))
arrPics[i].image = UIImage(named: arrSlide[i])
self.scrollView.addSubview(arrPics[i])
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.width, self.scrollView.frame.height*4)
}
Don't use a scroll view but either a table view or a collection view.
The delegates of both classes want a cell count from you. Then give the delegates an insane number of cells, a number so high that it is totally unlikely that any human being will ever scroll to reach the end. Something like 9999999 cells. This is no problem for such classes because in the background implementation they do not create really this high number of cells but only maximal the number of cells which could be visible at the same time on the screen. The cells in fact are reused. So when cells are falling out at the bottom those cells are going to be reused at the top and vice versa. As a last point is: set the starting point in the middle of such a high number, something like 5555555. I think that is the easiest solution if you are not going to implement a full image recycling algorithm like they did.
#IBOutlet weak var scrollView: UIScrollView!
var scrollViewHeight: CGFloat!
let numPics: Int = 4
override func viewDidLoad()
{
super.viewDidLoad()
scrollView.delegate = self
self.scrollView.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
let scrollViewWidth: CGFloat = self.scrollView.frame.width
scrollViewHeight = self.scrollView.frame.height
let imgOne = UIImageView()
let imgTwo = UIImageView()
let imgThree = UIImageView()
let imgFour = UIImageView()
let imgFive = UIImageView()
var arrPics = [imgOne, imgTwo, imgThree, imgFour,imgFive]
var arrSlide = ["slide1.jpeg", "slide1.jpeg", "slide1.jpeg", "slide1.jpeg","slide1.jpeg"]
for i in 0...numPics {
arrPics[i] = UIImageView(frame: CGRectMake(0,scrollViewHeight * CGFloat(i),scrollViewWidth, scrollViewHeight))
arrPics[i].image = UIImage(named: arrSlide[i])
self.scrollView.addSubview(arrPics[i])
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.width, self.scrollView.frame.height * CGFloat(numPics+1))
}
func scrollViewDidScroll(scrollView: UIScrollView)
{
scrollViewHeight = self.scrollView.frame.height
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.width, self.scrollView.frame.height * scrollViewHeight )
}
Using Timer you can use infinite scrolling like below
func showview() {
if(videosimageslider.isEmpty) {
// print("Empty Array")
} else {
// print("Not Empty ")
// print(videosimageslider.count)
for var index=0; index<videosimageslider.count; index++ {
if let url = NSURL(string: videosimageslider[index]) {
if let data = NSData(contentsOfURL: url){
if let imageUrl = UIImage(data: data) {
let myimageview:UIImageView = UIImageView()
// myimageview.image = imageUrl
let block: SDWebImageCompletionBlock! = {(image: UIImage!, error: NSError!, cacheType: SDImageCacheType, imageUrl: NSURL!) -> Void in
//println(self)
}
// let url = NSURL(string: "http://yikaobang-test.u.qiniudn.com/FnZTPYbldNXZi7cQ5EJHmKkRDTkj")
myimageview.sd_setImageWithURL(url, completed: block)
myimageview.frame.size.width = imagewidth
myimageview.frame.size.height = imageheight
myimageview.contentMode = UIViewContentMode.ScaleToFill
myimageview.frame.origin.x = xscrollpos
myimageview.frame.origin.y = 5
scrollview!.addSubview(myimageview)
xscrollpos += imagewidth
scrollviewcontentSize += imagewidth
scrollview.contentSize = CGSize(width: scrollviewcontentSize, height: imageheight)
}
}
}
}
scrollingTimer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "newStartScrolling", userInfo: nil, repeats: true)
scrollingTimer.fire()
}
}
// call the timer function //
func newStartScrolling() {
var currentOffset = scrollview.contentOffset
currentOffset = CGPointMake(currentOffset.x+3, currentOffset.y )
if(currentOffset.x < scrollview.contentSize.width - 500) {
scrollview.setContentOffset(currentOffset, animated: false)
currentOffset = CGPointMake(0, currentOffset.y )
//scrollview.contentSize = CGSize(width: 0, height: 0);
} else {
scrollingTimer.invalidate()
showview()
}
}
This is what will solve your problem, just adjust the controller to go in vertical slide view and load the resources at your will.
Link