How to add an Image to an ScrollView in Swift - ios

I develop an App in Xcoode and I add an ScrollView. Now I added some little Images in a Row.
let myImages = ["BallBeispielBlau.png","BallBeispielRot.png","BallBeispielGelb.png","BallBeispielBlau.png","BallBeispielRot.png","BallBeispielGelb.png","BallBeispielBlau.png","BallBeispielRot.png","BallBeispielGelb.png"]
let imageWidth:CGFloat = 66
let imageHeight:CGFloat = 66
var xPosition:CGFloat = 0
var scrollViewSize:CGFloat=0
for image in myImages {
let myImage:UIImage = UIImage(named: image)!
let myImageView:UIImageView = UIImageView()
myImageView.image = myImage
let LongTapGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "InfosZuEinemEvent:")
LongTapGestureRecognizer.minimumPressDuration = 1.0;
myImageView.addGestureRecognizer(LongTapGestureRecognizer)
myImageView.userInteractionEnabled = true
myImageView.frame.size.width = imageWidth
myImageView.frame.size.height = imageHeight
myImageView.frame.origin.x = xPosition
myImageView.frame.origin.y = 0
ScrollViewFreunde.addSubview(myImageView)
ScrollViewFreunde.showsHorizontalScrollIndicator = false
xPosition += imageWidth
scrollViewSize += imageWidth
}
ScrollViewFreunde.contentSize = CGSize(width: scrollViewSize, height: imageHeight)
That works fine but I want it that the six image so the image which come after the five image where show under the first image so in the second row. I try it with an if statement but it doesn´t work. I hope you could help me.
Thanks for help.

You should reeeeally use a Collection View for this. It is really easy and way better to display items in a matricial form.
However, to answer your question...
You can create a "yPosition" variable that will be incremented by imageHeight every time one image overflows the scrollView visible frame.
When this happens, xPositions goes to 0.
var yPosition = 0
for image in myImages {
let myImage:UIImage = UIImage(named: image)!
let myImageView:UIImageView = UIImageView()
myImageView.image = myImage
let LongTapGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "InfosZuEinemEvent:")
LongTapGestureRecognizer.minimumPressDuration = 1.0;
myImageView.addGestureRecognizer(LongTapGestureRecognizer)
myImageView.userInteractionEnabled = true
myImageView.frame.size.width = imageWidth
myImageView.frame.size.height = imageHeight
myImageView.frame.origin.x = xPosition
myImageView.frame.origin.y = yPosition
ScrollViewFreunde.addSubview(myImageView)
ScrollViewFreunde.showsHorizontalScrollIndicator = false
xPosition += imageWidth
if xPosition + imageWidth >= view.frame.width {
xPosition = 0
yPosition += imageHeight
}
scrollViewSize += imageWidth
}

You should prefer collectionview instead of scrollview. Its just a suggestion.

I've wrote a stack view for this reason, you can download a sample project at:
https://github.com/mcmatan/StackViewWithAutoLayout
Its pretty straight forward, you just call "addSubviewWithLayout" and add your view.
The stack view will manage the scroll content size.
You can call "removeViewWithLayout" to remove a view from the stack.
Cheers

Related

(Swift) Move Button To Random Location With Exceptions

I'm trying to move a label to a random location which I have been able to do so using this code.
let buttonWidth = self.samea.frame.width
let buttonHeight = self.samea.frame.height
// Find the width and height of the enclosing view
let viewWidth = self.samea.superview!.bounds.width
let viewHeight = self.samea.superview!.bounds.height
// Compute width and height of the area to contain the button's center
let xwidth = viewWidth - buttonWidth
let yheight = viewHeight - buttonHeight
// Generate a random x and y offset
let xoffset = CGFloat(arc4random_uniform(UInt32(xwidth)))
let yoffset = CGFloat(arc4random_uniform(UInt32(yheight)))
// Offset the button's center by the random offsets.
self.newButtonX = xoffset + buttonWidth/2
self.newButtonY = yoffset + buttonHeight/2
self.samea.center.x = self.newButtonX!
self.samea.center.y = self.newButtonY!
The problem is, I have some buttons and labels on the storyboard and I do not want the button to spawn on top of those. Not sure how to do that. Any help is appreciated !
You can create an array property of all the UIButton and UILabel outlets that you have, populate it in your viewDidLoad(_:) method. Then when you're generating your random values, you can put them in a while loop and cycle through the values.
Something like this.
let buttonsAndLabels = [UIView]()
var xoffset: CGFloat
var yoffset: CGFloat
var isOccupied = true
while isOccupied {
xoffset = CGFloat(arc4random_uniform(UInt32(xwidth)))
yoffset = CGFloat(arc4random_uniform(UInt32(yheight)))
let frame = CGRect(x: xoffset, y: yoffset, width: buttonWidth, height: buttonHeight)
isOccupied = false
for view in buttonsAndLabels {
if view.frame.intersects(frame) {
isOccupied = true
}
}
}

UIImage wont recognize tap gesture Swift

I'm trying to add a tap gesture recognizer to some UIImages that are in a side scrollview, but the images flat out won't recognize the tap and I can't see where I went wrong. I've tried "scrollView.bringSubViewToFront(imgView)" because I figured they might be getting buried in layers of other views, but that didn't do the trick either. "contentView" is the UIImageView in question, where my scrollView is just a collection of those. Any help here would be appreciated, thank you.
//function to create contentScrollView for MiniMatches
func setupMiniContentScroll(contentScroll: UIScrollView) {
let scalar:Double = 4/19
let contentViewDimension = contentScroll.frame.width * CGFloat(scalar)
let contentScrollWidth = CGFloat(LocalUser.matches.count) * (contentViewDimension + CGFloat(12)) - CGFloat(12)
let matchManager = MatchesManager()
for index in 0..<LocalUser.matches.count {
let match = LocalUser.matches[index]
matchManager.retrieveMatchThumbnail(match) { img, error in
if let img = img {
//create the mini matches views
let xOrigin = index == 0 ? 12 : CGFloat(index) * contentViewDimension + (CGFloat(12) * CGFloat(index) + CGFloat(12))
let contentFrame = CGRectMake(xOrigin, 10, contentViewDimension, contentViewDimension)
let contentView = self.makeMiniContentView(contentFrame, image: img, matchedPrice: match.matchedPrice)
let tap = UITapGestureRecognizer(target: self, action: #selector(BrowseViewController.toggleItemInfo(_:)))
contentView.addGestureRecognizer(tap)
self.miniMatchContainer.append(contentView)
//update the contentScrollView
dispatch_async(dispatch_get_main_queue()) {
let contentLabelFrame = CGRect(x: xOrigin, y: contentFrame.height + 15, width: contentFrame.width, height: 20)
let contentLabel = self.makeMiniContentLabel(contentLabelFrame, itemName: match.itemName)
let priceLabel = self.makeMiniPriceLabel(contentFrame, matchedPrice: match.matchedPrice)
contentScroll.addSubview(contentView)
contentScroll.addSubview(contentLabel)
contentScroll.addSubview(priceLabel)
contentScroll.contentSize = CGSizeMake(contentScrollWidth + CGFloat(16), contentScroll.frame.height)
}
}
}
}
}
Did you set UIImage property userInteractionEnabled to true?

view placed differently on iphone and ipad

i have built an app that allows the user to take their picture with a selection of glasses overlaid. it is working exactly how i want it on both an ipad and ipad mini but on the iphone the position in relation the the scroll view is wrong (see Images).
func setupPages(){
pageImages = [
UIImage(named: "glasses_one")!,
UIImage(named: "glasses_two")!,
UIImage(named: "glasses_three")!,
UIImage(named: "glasses_four")!,
UIImage(named: "glasses_five")!,
UIImage(named: "glasses_six")!
]
let pageCount = pageImages.count
for _ in 0..<pageCount {
pageViews.append(nil)
}
print(pageViews.count)
let pagesScrollViewSize = scrollView.frame.size
scrollView.contentSize = CGSize(width: scrollWidth * CGFloat(pageImages.count),
height: pagesScrollViewSize.height)
scrollView.backgroundColor = UIColor.blueColor()
loadVisiblePages()
}
func loadVisiblePages() {
let pageWidth = scrollView.frame.size.width
page = Int(floor((scrollView.contentOffset.x * 2.0 + pageWidth) / (pageWidth * 2.0)))
print(page)
pageControl.currentPage = page
for index in 0...5 {
//print(" -- Index = \(index)")
loadPage(index)
}
}
func loadPage(page: Int) {
if page < 0 || page >= pageImages.count {
// If it's outside the range of what you have to display, then do nothing
return
}
// 1
if let pageView = pageViews[page] {
print(pageView.description)
// Do nothing. The view is already loaded.
} else {
// 2
var frame = scrollView.bounds
frame.origin.x = scrollWidth * CGFloat(page)
frame.origin.y = 0.0
frame.size.width = scrollWidth
// 3
let newPageView = UIImageView(image: pageImages[page])
newPageView.contentMode = .ScaleAspectFit
newPageView.frame = frame
newPageView.clipsToBounds = false
scrollView.addSubview(newPageView)
// 4
pageViews[page] = newPageView
}
}
Ipad
Iphone
I think your issue is you need to add a constraint to center you image vertically. Or you could also solve this by making the frame for your "glasses frame" A set width and height. Smaller screens will have less space around it but will still be in the middle.

Scroll View with images in a Horizontal (like the Youtube App) in Swift

I want to learn Swift and I want to make an app with a ScrollView like it is in the YouTube App.
The scrollview I make in the storyboard.
I try it with this code:
let myImages = ["ImageGelb.png","ImageGrün.png","ImageRot.png"]
let imageWidth:CGFloat = 66
let imageHeight:CGFloat = 66
var xPosition:CGFloat = 0
var scrollViewSize:CGFloat=0
var index=0
index<=myImages.count
index++
let myImage:UIImage = UIImage(named: myImages[index])!
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 = 10
ScrollViewNeuesFreunde.addSubview(myImageView)
xPosition += imageWidth
scrollViewSize += imageWidth
ScrollViewNeuesFreunde.contentSize = CGSize(width: scrollViewSize, height: imageHeight)
but it doesn´t work. Only the "ImageGrün.png" is on the screen and the ScrollView does´t work.
Could someone help me?
You are not incrementing your index except for one time. index = 0, then you incremented it with index++, giving you the picture at index 1 of your array. You want to use a for loop.
let myImages = ["ImageGelb.png","ImageGrün.png","ImageRot.png"]
let imageWidth:CGFloat = 66
let imageHeight:CGFloat = 66
var xPosition:CGFloat = 0
var scrollViewSize:CGFloat=0
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 = 10
ScrollViewNeuesFreunde.addSubview(myImageView)
xPosition += imageWidth
scrollViewSize += imageWidth
}
ScrollViewNeuesFreunde.contentSize = CGSize(width: scrollViewSize, height: imageHeight)
This way you don't need an index, as Swifts fast enumeration takes care of it for you. For more on this check out this link.https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ControlFlow.html#//apple_ref/doc/uid/TP40014097-CH9-ID121

UIImageViews not scaling correctly in UIScrollView with paging

I'm trying to build a very simple UIScrollView with several images where paging is enabled.
However, I can't seen to get the images to correctly be resized to the bounds of my UIScrollView. The images are always bigger than the bounds, thus messing with my paging.
I have a UIScollView and a UIPageControl in Interface Builder and link it in my ViewController swift file.
Here is my viewDidLoad method (pageImages is defined as var pageImages: [UIImage] = [] and pageViews as var pageViews: [UIImageView?] = []:
override func viewDidLoad() {
scrollView.delegate = self
scrollView.pagingEnabled = true
scrollView.scrollEnabled = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.showsVerticalScrollIndicator = false
scrollView.bounces = true
scrollView.scrollsToTop = false
pageImages = [UIImage(named: "image1")!,
UIImage(named: "image2")!,
UIImage(named: "image3")!,
UIImage(named: "image4")!,
UIImage(named: "image5")!]
let pageCount = pageImages.count
pageControl.currentPage = 0
pageControl.numberOfPages = pageCount
for (var i=0; i<pageCount; i++) {
var xOrigin: CGFloat = CGFloat(i) * scrollView.bounds.size.width
let imageView: UIImageView = UIImageView(frame: CGRectMake(xOrigin, 0, scrollView.bounds.size.width, scrollView.bounds.size.height))
imageView.image = pageImages[i]
imageView.contentMode = UIViewContentMode.ScaleAspectFill
imageView.clipsToBounds = true
scrollView.addSubview(imageView)
}
let pagesScrollViewSize = scrollView.frame.size
scrollView.contentSize = CGSize(width: pagesScrollViewSize.width * CGFloat(pageImages.count),
height: pagesScrollViewSize.height)
}
My scrollViewDidScroll method is as follows:
func scrollViewDidScroll(scrollView: UIScrollView) {
let pageWidth = self.scrollView.frame.size.width
let page = Int(floor((self.scrollView.contentOffset.x - pageWidth/2)/pageWidth) + 1)
self.pageControl.currentPage = page
}
Can anyone spot my mistake? Do I have to set the contentMode maybe in viewWillAppear or viewDidAppear?
Try setting up your imageViews sizes under:
(void)viewDidLayoutSubviews
At this point, autolayout had finished resizing your views/subviews according to the layout system you defined on interface builder so if your calculations are correct (according your requirements) this should work out fine.

Resources