Is it possible to design the below UI using tableview ?
I know, I can define numberOfSections in the tableview. In each cell, I can define number of column. But, i am not sure how to add the image in the tableView ? What i understand is the image will be on the right side merging some cells. But how to do it or is it possible or not ?
Any help will be highly appreciated.
You will not be able to add an image to those 4 cells at once.
As I see it, there are two options:
create a single cell for those 4 cells, in which use UIStackViews or just autolayout to lay the contents out along with the image.
Change the tableView to a collectionView with custom layout implementation, then you can have the image as a single cell laid out to the right of those cells.
I myself would chose the first approach, because I believe it will be easier and faster to implement.
Yeah its possible. You need to do some calculation for Y Position, trailing space from tableview, etc
Add your image view into tableView.
let imageWidth: CGFloat = 150.0
let imageHeight: CGFloat = 150.0 //Addition of height of meging cells
let trailingSpace: CGFloat = 25.0
let yPosition: CGFloat = 100 //Calculate Y position depend on NavigationBar, Name cell, etc...
let imgView = UIImageView(frame: CGRect(x: view.frame.width - imageWidth - trailingSpace, y: yPosition, width: imageWidth, height: imageHeight))
imgView.backgroundColor = .clear
imgView.image = UIImage(named: "Waterfall")
imgView.contentMode = .scaleAspectFit
tableView.addSubview(imgView)
Related
I currently have a ScrollView and inside the ScrollView i have a UIImageView.
I get different image sizes from my server and most images are larger than the bounds of my screen.
I would like to scroll through the image if it is bigger than my screen.
Something like this....
This is what i have tried so far.
let image = UIImage(named: "myImg")
let heightInPoints = image?.size.height
let heightInPixels = heightInPoints ?? 0 * image!.scale
let widthInPoints = image?.size.width
let widthInPixels = widthInPoints ?? 0 * image!.scale
self.imageView.frame = CGRect(x: 0, y: 0, width: widthInPixels, height: heightInPixels) //= image
self.imageView.image = image
scrollView.contentSize = CGSize(width: imageView.frame.width, height: imageView.frame.height)
But it doesn't seem to work. Either it only scrolls vertically or horizontally or it never scrolls.
What am I doing wrong. Or is there a better approach to get this effect ?
Solution 1. Updating Frames
Firstly, make sure the views hierarchy is correctly setup (the imageView is added to the scrollView):
scrollView.addSubview(imageView)
Then I'd suggest rewriting this code as something like:
let image = UIImage(named: "myImg")
imageView.image = image // setup image to imageView
imageView.frame.size = image?.size ?? .zero // setup image size or zero to imageView
scrollView.contentSize = image.size ?? .zero // setup image size or zero as a content size
Solution 2. Using constraints
There is also another solution using constraints instead of manually setting up the sizes. This takes a bit more code but doesn't require sizes recomputing when you change the image.
scrollView.addSubview(imageView) // Setup the views hierarchy
imageView.translatesAutoresizingMaskIntoConstraints = false // Make sure constraints won't interfere with autoresizing mask
NSLayoutConstraint.activate(
[
imageView.leftAnchor.constraint(equalTo: scrollView.leftAnchor), // attaching to the left
imageView.topAnchor.constraint(equalTo: scrollView.topAnchor), // attaching to the top
imageView.rightAnchor.constraint(equalTo: scrollView.rightAnchor), // attaching to the right
imageView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor) // attaching to the bottom
]
)
Then we replace existing image with a new one like this:
imageView.image = UIImage(named: "myImg")
Both approaches work for me in Playground. So, if these still won't work for you, please share more information about how you set up the hierarchy and additional parameters of the scroll view.
I have at problem with my cells in a UITableView. I have used the Attribute Inspector to adjust the size. Like this:
But the adjustment only applied on the cells with content. How do I make the separator to be the same size for the whole tableview using Swift or the Attribute Inspector?
For your question, you can try this
tableView.tableFooterView = UIView()
Another way you can do like this.
Then,
In cellForRowAtIndexPath
tableView.separatorStyle = .none
let horizontalGap = 15.0 as CGFloat
// As you want to have equal gaping in left & right side, you have to position the view's origin.x to the constant and have to have the width minus the double of that constant.
let seperatorView = UIView(frame: CGRect(x: horizontalGap, y: cell.frame.size.height - 1, width: cell.frame.size.width - horizontalGap * 2.0, height: 1))
seperatorView.backgroundColor = UIColor.red
cell.addSubview(seperatorView)
In Storyboard
Change Separator as None in Attributes Inspector. Drag UIView and place it inside your cell . Give constraints like, Leading 15, Trailing 15, Bottom 0 and height 1. Change background color to red
I am working on an UICollectionView where I have to rotate a label in the UICollectionViewCell. Before scrolling up/down it looks perfect. But once I scrolled the UICollectionView the label retransform to the status it was before.
Before Scrolling :
After Scrolling :
The code I used :
cell.lblName?.frame = CGRect(x: 15, y: (((self.collectionView?.frame.size.height)!/3)/2) - 20, width: cell.frame.size.height , height: 40)
cell.lblName?.backgroundColor = UIColor.red
cell.lblName?.transform = CGAffineTransform(rotationAngle: CGFloat((Double.pi/2) * 3))
Well, I did test for my self and its working perfectly, what i have done is
cell.label.transform = CGAffineTransform(rotationAngle: CGFloat.pi / 2)
and i did useAutolayout, and it working as expected.
Follow the image bellow:
Cell ImageView and UILabel with Autolayout
Hope this help you.
Thanks
EDITED
Use cell.label.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2) for your type rotation.
You just need rotate view which are taken inside the cell.
Write this code snippet in cellForItem dataSource method of collection view.
cell.viewDemo.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
I am trying to create a grey space between the header view (with the two buttons) and the dynamic tableview as shown here:
This is what I was able to create so far:
Now there is a line between the header view and the dynamic table view. However, I would like to have a grey space as shown in the picture above. I tried using Grouped instead of Plain. And I hypothesize that this is a way to achieve my goal because it does add grey to my view like so but only at the bottom:
So I figured if I can add some padding unto my headerview, that cause the grey to show since I think the background is grey now. So I tried writing some code:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let headerView = taskListTableView.tableHeaderView
headerView!.setNeedsLayout()
headerView!.layoutIfNeeded()
let cGPoint = CGPoint(x: 0.0, y: 0.0)
let cGHeight = CGSize.init(width: 0, height: 10)
var frame = headerView!.frame
headerView!.bounds = CGRect(origin: cGpoint, size: cGHeight)
frame.size.height = CGFloat(30.0)
headerView!.frame = frame
taskListTableView.tableHeaderView = headerView
}
But this code is won't compile. Am I on the right track? What else could I do to achieve this effect?
I have a tableView using IB with custom cells and prototype cells.
I'm trying to make the cells a little shorter in width than the tableView.frame to leave a little space between the left and right corners.
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as TableViewCell
cell.bounds = CGRectMake(10, self.tableView.frame.origin.y, 30, self.tableView.frame.size.height)
cell.layer.bounds = CGRectMake(10, self.tableView.frame.origin.y, 30, self.tableView.frame.size.height)
cell.textLabel?.bounds = CGRectMake(10, self.tableView.frame.origin.y, 30, self.tableView.frame.size.height)
Update: here is a good example explaining how to add a subView to your tableView.
http://natashatherobot.com/ios-frame-vs-bounds-resize-basic-uitableview-cell/
Update 2: Looks like there isn't an easy way to do this. There are 3 ways of achieving this as far as I know:
Add a rounded and a shorter image to your cell that has the same exact color and matches your background.
You could subclass tableViewCell and then play with the layoutSubviews, this way you can make it shorter before it draws the cell. I've done it but the scrolling performance sucks.
The best way is to ditch the tableView altogether and re-do it with a collectionView.
The cells in the tableview are supposed to be as wide as their container.
If you need your cells to have a different width than the table view, I would suggest adding a view as subview to cell.contentView and make that view as wide as you need while making sure the contentView has clear background and no separator and all (so that it appears it is not there).
Another solution would be to have the tableView not as wide as it's superview by adding the left/right padding to it. But the you would have the issue that on the left and right side, where the padding is, you won't be able to scroll the tableView
I consider the cleanest solution to use a collectionView. It is not that much different than a tableView and you can configure the entire size of the cell, not just the height.
Hope this helps you fix your problem. Let me know if you need more help.
Swift 3:
For people still looking for a good solution, there's an easier and more effective alternative to using layoutSubviews or re-doing the whole thing with collectionView.
If you have already subclassed the tableViewCell, then in your TableViewController class you can add this to add a plain white border to each side of the table view cell.
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// make sure in storyboard that your cell has the identifier "cell" and that your cell is subclassed in "TableViewCell.swift"
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! TableViewCell
// the following code increases cell border on all sides of the cell
cell.layer.borderWidth = 15.0
cell.layer.borderColor = UIColor.white.cgColor
return cell;
}
If you want to add different sized borders to each side of the cell, you can also do this:
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! TableViewCell
// the following code increases cell border only on specified borders
let bottom_border = CALayer()
let bottom_padding = CGFloat(10.0)
bottom_border.borderColor = UIColor.white.cgColor
bottom_border.frame = CGRect(x: 0, y: cell.frame.size.height - bottom_padding, width: cell.frame.size.width, height: cell.frame.size.height)
bottom_border.borderWidth = bottom_padding
let right_border = CALayer()
let right_padding = CGFloat(15.0)
right_border.borderColor = UIColor.white.cgColor
right_border.frame = CGRect(x: cell.frame.size.width - right_padding, y: 0, width: right_padding, height: cell.frame.size.height)
right_border.borderWidth = right_padding
let left_border = CALayer()
let left_padding = CGFloat(15.0)
left_border.borderColor = UIColor.white.cgColor
left_border.frame = CGRect(x: 0, y: 0, width: left_padding, height: cell.frame.size.height)
left_border.borderWidth = left_padding
let top_border = CALayer()
let top_padding = CGFloat(10.0)
top_border.borderColor = UIColor.white.cgColor
top_border.frame = CGRect(x: 0, y: 0, width: cell.frame.size.width, height: top_padding)
top_border.borderWidth = top_padding
cell.layer.addSublayer(bottom_border)
cell.layer.addSublayer(right_border)
cell.layer.addSublayer(left_border)
cell.layer.addSublayer(top_border)
return cell;
}
Hope this helps.
I found the other answers unhelpful/incorrect, but found what I needed in one of the answers here:
How to set the width of a cell in a UITableView in grouped style
The key is, if you have a custom cell (which OP has, and most apps would have anyway), then you can override the setFrame method to whatever width you need. No need to redesign your app or do anything tricky.