Does anyone Know how to implement this design (in swift)? - swift

The profiles get pulled in from a server but I don't know how to implement this. Had been thinking about a dynamic table view, but I don't know if you can draw cells like that. The pictures have to be clickable.

Add A UICollectionView to your screen. In the collection view cell, place a image view, then use this code to create the blue border and circle image...
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell:UICollectionViewCell = self.collectionView.dequeueReusableCellWithReuseIdentifier("BasicCell", forIndexPath: indexPath) as UICollectionViewCell
let imageView = cell.viewWithTag(1) as! UIImageView
//border
imageView.layer.borderWidth = 2.0
imageView.layer.borderColor = UIColor.blueColor().CGColor
//make imageView Circle
imageView.layer.cornerRadius = imageView.frame.size.width / 2
imageView.clipsToBounds = true
return cell
}

UICollectionView is probably what you're looking for (to display like on your screen capture : sections / items).
UICollectionView Class Reference : https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionView_class/
It's similar as working with UITableView. Still, you might want to read some tutorials about it.

What you want is UICollectionView. Think of it as the generic version of UITableView.

Related

Image does not fit properly in collectionCell

In Swift 3. My app has a table view and a detail view with is a view controller. Here I added a collection view. An array of images must be presented. The images adapt themselves beautifully if in portrait I check the content mode in scaler to fill. In ladscape it works in aspectFill. Vice-versa, the layout does not fit. I did the following
in cellForItem At:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = myCollection.dequeueReusableCell(withReuseIdentifier: "cellCollection", for: indexPath) as! CollectionViewCell
cell.cellImage.image = UIImage(named: array[indexPath.item])
if UIDevice.current.orientation.isLandscape{
cell.cellImage.contentMode = .scaleAspectFill
}
else if UIDevice.current.orientation.isPortrait{
cell.cellImage.contentMode = .scaleToFill
}
return cell
}
It does not work. May be I have some inconsistencies from portrait to landscape.
I would appreciate your help. If you want to take a look at the project in git:
[https://github.com/ricardovaldes/tareaFinalHoteles.git1. Thanks in advance.
Eureka. Finally I did solve this problem. With sizeForItem at, the app could function without problems. I was lost or mislead looking for a way to change the image content mode, but this is not the right way. The correct way is resize once you rotate: for this you need the func willTransition toNewCollection: UITraitCollection. Inside you create a variable layout that is of type UICollectionViewFlowLayout. With the help of a conditional, is possible to define how you want the with and heigt after rotation.This post is clear and concise for those curious: UICollectionView Cell Resizing on Device Rotation.
Here the implementation I did in my project: `
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.current.orientation.isLandscape,
let layout = myCollection.collectionViewLayout as? UICollectionViewFlowLayout{
let with = myCollection.frame.size.width
layout.itemSize = CGSize(width: with, height: 280)
layout.invalidateLayout()
}
else if UIDevice.current.orientation.isLandscape,
let layout = myCollection.collectionViewLayout as? UICollectionViewFlowLayout{
let with = myCollection.frame.size.width
layout.itemSize = CGSize(width: with/2, height: 280)

Cell loaded in cellForItemAt, but not in visibleCells

I have a custom UICollectionView and the cells are loaded in cellForItemAt but when I try to get all the visible cells by using visibleCells I'm not getting all the cells.
For example, in cellForItemAt, I'm setting the alpha of the labels in the cells to 0. When panned, I want the alpha of those labels change to 1:
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
handleLabel(scrollView, active: true)
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if pickerIsActive { handleLabel(scrollView, active: false) }
}
private func handleLabel(_ scrollView: UIScrollView, active: Bool) {
guard let pickerView = scrollView as? UICollectionView else { return }
let cells = pickerView.visibleCells.flatMap { $0 as? CustomCell }
panningIsActive = active
UIView.animate(duration: 0.3) {
cells.forEach { $0.label.alpha = $0.isSelected || active ? 1 : 0 }
}
}
And cellForItemAt:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
cell.label.alpha = 0
return cell
}
What can I do to change all the "loaded" cells instead of just the "visible" cells?
The visibleCells are only the on screen cells. This used to be everything initialized in cellForItem:at: but as of iOS 10 UICollectionView now prefetches to improve scrolling performance (see WWD 2016 video) which maybe why you are having this problem. Anyways it sounds like all you want to do is animate the cells to fade in when they come on screen. You can either move your animation logic to willDisplayCell or subclass UICollectionViewCell. UIColectionViewCell inherits from UIView, so you can override didMoveToSuperView in your UICollectionViewCell and call your animation method there, which will cause the cell to animate as it appears.
I am using Xcode 11.4 and Swift 5, and I had the exactly the same issue: .visibleCells is not giving me all the loaded cells.
By reading #Josh Homann's answer and the comments below, I figured out 2 solutions.
The first solution is same as the solution you reached at: customize cell appearance in collectionView(_:willDisplay:_:) after it's loaded but before it's displayed on the screen.
Another quick and dirty solution is to simply uncheck UICollectionView's 'Prefetch' option in attributes inspector.
This fixes the issue because by disabling prefetching, UICollectionView will stop pre-loading cells that are not displayed on the screen, so .visibleCells are now all the loaded cells. This solution will work fine if you're simply loading static or small local data in the cells. If you're prefetching large data (e.g. images) from network for upcoming cells, you probably need Prefetching Enabled, then solution 1 is your go-to option.
It sounds like you might want to try using layoutAttributesForElements(in:).
You'll need to implement your own collection view layout subclass (rather than using the delegate methods) but I think it will be worth it in the long term.
Rather than manually managing the animations (via UIView.animateWithDuration) you use this method to tell the collection view what properties cells should have at different positions, and as people pan the collection view, the correct properties are automatically applied.
I tried to find a good Swift reference for this, but I could't, but here's a post in Objective-C that you can follow if you want to try this approach:
https://bradbambara.wordpress.com/2014/05/24/getting-started-with-custom-uicollectionview-layouts/

UITableView, Image in cell isn't showing, despite showing in UI View Hierachy inspector

I use a UITableView with custom UITableViewCells. In the cells I have a UIImageView. I assign an image to that image view from a url from my model. All this have been working fine until now.
When the cell is returned in cellForRowAtIndexPath, the image is fetched through a UIImageView extension and assigned to the image property when the async fetch returns.
The image doesn't show in the UIImageView, dispite having worked before (maybe this problem occured after Xcode 8 was released)
What's even more strange, it appear right in the UI View Hierachy Inspector in Xcode.
What's going on??
Screenshot from device:
Screenshot from UI View Hierachy Inspector in Xcode
Move your code that changes corner radius from awakeFromNib to layoutSubviews in your cell subclass like the example below. This should fix it.
override func layoutSubviews() {
super.layoutSubviews()
self.contentView.layoutIfNeeded()
imageView.layer.cornerRadius = CGRectGetHeight(imageView.bounds) / 2.0
imageView.clipsToBounds = true
}
You can also try changing it in your tableView class.
Like this:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellIdentifier", for: indexPath) as! yourCellClassName //Change this to your cell
cell.imageView.layer.cornerRadius = 6
cell.imageView.clipsToBounds = true
return cell
}
Hope it will help you.

Corner radius of a UIButton in UICollectionViewCell not working

I have a UICollectionView in a ViewController of type ANY-ANY storyboard and using auto-layout with swift. I have changed the size of ViewController to iPhone 5 screen size.
The problem is that, there is a button inside the UICollectionViewCell and I am trying to make that circular. When I run in iPhone 5 the button gets in circular fine, But if I run in iPhone 6 or 6+ it doesn't come in circular.
Below is the code i am using in "cellForItemAtIndexPath"
var btnImage = cell.contentView.viewWithTag(100) as UIButton
btnImage.layer.masksToBounds = true
btnImage.layer.cornerRadius = btnImage.frame.size.height/2
The result of this code is as below
And if I use below code
var btnImage = cell.contentView.viewWithTag(100) as UIButton
btnImage.layoutIfNeeded()
btnImage.layer.masksToBounds = true
btnImage.layer.cornerRadius = btnImage.frame.size.height/2
The result is as below
Does anyone have any Idea about this issue.
Thanks in advance.
The solution that worked for this issue is below:
cell.contentView.frame = cell.bounds //This is important line
var btnImage = cell.contentView.viewWithTag(100) as UIButton
btnImage.layoutIfNeeded() //This is important line
btnImage.layer.masksToBounds = true
btnImage.layer.cornerRadius = btnImage.frame.size.height/2
Above code makes the button complete circular.
Roundrect not working with collection view cell can not be the case. I have just created a demo application to test that and it works. Below is code from my demo.
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell:CollectionCell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CollectionCell
// Configure the cell
cell.roundTestButton.layer.cornerRadius = 10.0
cell.roundTestButton.layer.masksToBounds = true
println(cell.roundTestButton)
return cell
}
Or here is git link of complete project.
This is due to autolayout constraint. As the height and width can increased after corner radius size is set.Try to set this in storyboard.

iOS8 Swift - Problems dynamically resizing tableview cells

Here's what my application looks like currently.
You'll see that when the subtitle text label is only one line is resizes correctly, but when there's multiple lines it gets all messed up. I think this has to do with the constraints possibly? Right now I'm using the auto-layout constraints. You can see them in the screenshot. Here's the code that creates my cells.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> DealCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Deal Cell", forIndexPath: indexPath) as DealCell
let currentBar = bars[indexPath.row] as BarAnnotation
cell.barName.text = currentBar.name
cell.deal.text = currentBar.deal
cell.distanceToBar.text = String(format: "%.3f mi", currentBar.distance)
// Set the height of the table view cells
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 44.0;
return cell
}
Any ideas?
Use tableView:heightForRowAtIndexPath: function in the UITableViewDelegate.
Using this you can individually set the height of each row separately.
For more information : https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/index.html#//apple_ref/occ/intfm/UITableViewDelegate/tableView:heightForRowAtIndexPath:
Or you can use auto layout settings like in this article.
http://useyourloaf.com/blog/2014/02/14/table-view-cells-with-varying-row-heights.html