Scroll view Does not show images but scrolls? - ios

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])

Related

Image Zoom not working in a UIScrollView inside a Root UIScrollView

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.

UIPageControl and UIScrollView not scrolling

I'm having a relatively simple UIViewController with a UIScrollView that's taking relatively half the screen and a UIImageView placed inside the UIScrollView that's the exact same size as the UIScrollView.
On top of the UIImageView there's a UIPageControl. The point is have a horizontal scrolling and present an image like a slider based on the amount of images in an array. The problem is that the scroll view is not scrolling and I don't know why.
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var pageControl: UIPageControl!
let imagelist = ["3.jpg", "1.jpg", "2.png", "4.png", "5.png"]
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
configurePageControl()
for i in stride(from: 0, to: imagelist.count, by: 1) {
var frame = CGRect.zero
frame.origin.x = self.scrollView.frame.size.width * CGFloat(i)
frame.origin.y = 0
frame.size = self.scrollView.frame.size
scrollView.isPagingEnabled = true
scrollView.isScrollEnabled = true
let myImage:UIImage = UIImage(named: imagelist[i])!
let bgColorFromImage = myImage.averageColor
imageView.image = myImage
imageView.contentMode = UIViewContentMode.scaleAspectFit
imageView.frame = frame
scrollView.backgroundColor = bgColorFromImage
scrollView.addSubview(imageView)
}
self.scrollView.contentSize = CGSize(width: self.scrollView.frame.size.width * CGFloat(imagelist.count), height: self.scrollView.frame.size.height)
pageControl.addTarget(self, action: #selector(changePage), for: UIControlEvents.valueChanged)
}
func configurePageControl() {
self.pageControl.numberOfPages = imagelist.count
self.pageControl.currentPage = 0
self.pageControl.tintColor = UIColor.red
self.pageControl.pageIndicatorTintColor = UIColor.black
self.pageControl.currentPageIndicatorTintColor = UIColor.green
self.imageView.addSubview(pageControl)
}
#objc func changePage() {
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)
}
This is what the UIStoryboard looks like:
Inside the for loop you use the same object of imageView , you only set the frame and the image
imageView.frame = frame
imageView.image = myImage
but you have to create a new instance of the UIImageView
//
Suppose you have a scrollView in IB with top , leading and trailing constraints to the superView , and a height of say 200 , you can add imageViews dynamically like this
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
for i in 0..<10 {
let f = CGRect(x: CGFloat(i) * scrollView.frame.width, y: 0, width: scrollView.frame.width, height: scrollView.frame.height)
let imgV = UIImageView(frame: f)
imgV.image = UIImage(named: "re-fuel.png")
scrollView.addSubview(imgV)
}
scrollView.contentSize = CGSize(width: CGFloat(10) * scrollView.frame.width, height: scrollView.frame.height)
}
}
Result
The problem is that the scroll view itself is positioned with autolayout. Once you do that, you cannot set the contentSize to make the scroll view scrollable. You must use internal constraints to configure the content size.

Horizontal ScrollView not fit its sub ImageViews?

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

Programmatically creating Label that shows Slider value on each scene on ScrollView

im kinda new to the programming world specifically on swift.
Ive started to practice a bit and im currently working on a demo app just to explore..
So right now what the app suppose to do is to show have a scroll view, and each screen shows a different "animal" or any other subject by an Image, a Label and an Icon, on the side theres a slider with 1-5 values which suppose to show how much you "love" that subject on a scale of 1 to 5.
everything works except I cant seem to add a label to each of the screens above the slider to show its current value.
with the current code it shows every screen with its appropriate image/label/icon, shows the right Page on the page indicator, and shows a working Slider,
only on the last frame the Slider have a Label that is connected to its value.
cant seem to figure it out
hopefully its clear enough, thanks alot.
(P.S Im fully aware that i might be doing this thing completely wrong in the first place, enlighten me its welcome)
class ViewController: UIViewController, UIScrollViewDelegate {
public var sliderLbl = UILabel()
#IBOutlet var mainScrollView: UIScrollView!
#IBOutlet var secondScrollView: UIScrollView!
var imageArray = [UIImage]()
var iconImg = [UIImage]()
var pageControl : UIPageControl = UIPageControl(frame: CGRect(x: 160, y: 420, width: 50, height: 100))
var subjects:[String] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
mainScrollView.delegate = self
mainScrollView.frame = view.frame
imageArray = [pic1.png, pic2.png, pic3.png, pic4.png, pic5.png]
subjects = ["Dog", "Cat", "Mouse", "Cow", "Snake"]
iconImg = [icon1.png, icon2.png, icon3.png, icon4.png]
for i in 0..<imageArray.count{
let labelView = UILabel()
let imageView = UIImageView()
let subjIcon = UIImageView()
let oneSlider = UISlider()
let sliderLabel = sliderLbl
sliderLabel.textColor = UIColor.black
oneSlider.transform = CGAffineTransform(rotationAngle: CGFloat(-M_PI_2))
oneSlider.minimumValue = 1
oneSlider.maximumValue = 5
oneSlider.isUserInteractionEnabled = true
oneSlider.value = 1
oneSlider.tintColor = UIColor.darkGray
oneSlider.isContinuous = true
sliderLabel.text = "1"
labelView.text = subjects[i]
labelView.textColor = UIColor.darkGray
labelView.textAlignment = .center
imageView.alpha = 0.85
imageView.image = imageArray[i]
imageView.contentMode = .center
subjIcon.image = iconImg[i]
subjIcon.contentMode = .scaleAspectFit
let xPosition = self.view.frame.width * CGFloat(i)
imageView.frame = CGRect(x: xPosition, y: -50, width: self.mainScrollView.frame.width, height: self.mainScrollView.frame.height)
labelView.frame = CGRect(x: xPosition, y: -250, width: self.mainScrollView.frame.width, height: self.mainScrollView.frame.height)
iconImg.frame = CGRect(x: xPosition, y: 500, width: self.mainScrollView.frame.width, height: 150)
oneSlider.frame = CGRect(x: xPosition, y: 250, width: 50, height: 130)
sliderLabel.frame = CGRect(x: xPosition+20, y: 180, width: self.mainScrollView.frame.width, height: 80)
mainScrollView.contentSize.width = mainScrollView.frame.width * CGFloat(i + 1)
// Add subViews
mainScrollView.addSubview(subjIcon)
mainScrollView.addSubview(imageView)
mainScrollView.addSubview(labelView)
mainScrollView.bringSubview(toFront: subjIcon)
oneSlider.addTarget(self, action: #selector(sliderSlid(_:)) ,for: UIControlEvents.valueChanged)
mainScrollView.addSubview(sliderLabel)
mainScrollView.addSubview(oneSlider)
func configurePageControl() {
self.pageControl.numberOfPages = imageArray.count
self.pageControl.currentPage = 0
self.pageControl.tintColor = UIColor.red
self.pageControl.pageIndicatorTintColor = UIColor.lightGray
self.pageControl.currentPageIndicatorTintColor = UIColor.green
self.view.addSubview(pageControl)
}
configurePageControl()
}
}
func sliderSlid(_ sender: UISlider) {
sliderLbl.text = String(Int(roundf(sender.value)))
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageNumber = round(mainScrollView.contentOffset.x / mainScrollView.frame.size.width)
pageControl.currentPage = Int(pageNumber)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Page control with image array

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)

Resources