UITableViewCell Custom Indentation Width - ios

My app includes a UITableViewController. The default indentation (while editing) is fine, except when on an iPad in landscape mode, when the indentation is way too wide. I've tried setting the indentationWidth and indentationLevel in cellForRowAtIndexPath but nothing seems to work.
I would like my code to work something like this:
override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("Cell",
forIndexPath: indexPath)
// do other cell configuration here
if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
// set the custom indentation level for the cell here
// Tried:
// cell.indentationWidth = 0.1
// cell.indentationLevel = 0
// both have absolutely no effect
}
}
The horrible indentation on iPad in landscape:
The same cells while not editing:
Thanks in advance for any help.

In viewDidLoad, add the following line:
self.tableView.cellLayoutMarginsFollowReadableWidth=NO;
The default setting is YES and that causes wide margins in landscape on newer iPads.

Related

Swift: Images placed in a tableviewcell are not visible

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "approve_cell");
let event = self.events[indexPath.row];
cell.textLabel?.text = event.name;
return cell;
}
I placed 2 images and a label in tableviewcell. When i run the app, images are not visible. What could be the reason?
Check that you are not using the basic style of the UITableViewCell because if you are then that style only includes labels.. no image views. Change it to subtitle or one of the details.
For reference, see: https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html
You probably forgot to set AutoLayoutConstraints of your image view. You could either add constraints to that image view through storyboard or through code. The other method is setting the frame of your image view in -(void)viewDidLayoutSubviews, because when you're using auto-layout, the layout of those views will be undefined if its constraints doesn't fulfill system's computing need. So you should either set right constraints or give a specific frame to those undefined views after all of the others has-constraints-views are arranged.
You creat cell in storyboard but you never use this cell created from storyboard. instead you manually creat it by UITableViewCell's designated initializer without override layout method of it.
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "approve_cell", for: indexPath)
let event = self.events[indexPath.row];
cell.textLabel?.text = event.name;
return cell;
}
You need to set either Autolayout or used Autoresizing. For autolayout just pinned the proper leading, trailing, top and bottom constraint.

Change UITableView direction to Right-to-Left

I develop an iOS application and my native language is Persian (a Right-to-Left language). How can I change UITableView direction to right-to-left in iOS programming?
A UITableView with RTL direction has:
Icons are at right
TableCell detail and button are at left
TableView header and footer are right-aligned
like this :
Is there any UI or programming way to do this?
Try this on Swift
tableView.semanticContentAttribute = .forceRightToLeft
or in StoryBoard Cell properties (Semantic dropdown) select "Force Right-To-Left"
As I'm aware it'll automatically change to Right-to-Left since iOS8.
You can try to do this as well
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = myTableView.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
cell.textLabel?.textAlignment = .Right
cell.textLabel?.text = goalsArray[indexPath.row]
return cell
}
Build your view's constraints with NSLayoutAttributeLeading and NSLayoutAttributeTrailing instead of NSLayoutAttributeLeft and NSLayoutAttributeRight.
Your view's Direction will be the same with your app's language Direction.
for me this way worked
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier)! as UITableViewCell
//cell.myView.backgroundColor = self.colors[indexPath.row]
cell.textLabel?.text =
"\((self.FAQs?[indexPath.row].Question)!)"
cell.textLabel?.textAlignment = .right
return cell
}

ios tableview displays cell as multiline only ios8 not ios7

I have a tableview that displays as multiple lines, as intended, when running the simulator under ios8. When running under ios7 it limits all the cells to 2 rows. The recommendation I found numerous places online was to use numberOfLines = 0 as seen below but this does nothing. Also tried sizeToFit and lineBreakMode and they have no effect. Any ideas? Creating custom cell seems like overkill but do I need to do that?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
// Configure the cell...
//cell.textLabel?.lineBreakMode = .ByWordWrapping
//cell.textLabel?.sizeToFit()
cell.textLabel?.numberOfLines = 0;
cell.textLabel?.text = "\(formattedPlateComments[indexPath.row])"
return cell
}
Setting numberOfLines=0 on the Label instance is correct, since this specifies an unlimited number of lines. For iOS 7 compatibility, however, you need to also define heightForRowAtIndexPath, i.e.:
func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
return 20 // you can also programmatically calculate a desired height
}
Using numberOfLines=0 and heightForRowAtIndexPath, I was able to display multiple lines in my tableView in both iOS 8 & 7.

UITableViewAutomaticDimension not working until scroll

When the Table View is first loaded, all of the visible cells are the estimatedRowHeight. As I scroll down, the cells are being automatically sized properly, and when I scroll back up the cells that were initially estimatedRowHeight are being automatically sized properly.
Once the cells are being automatically sized, they don't ever seem to go back to being the estimatedRowHeight.
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
self.tableView.estimatedRowHeight = 80.0
self.tableView.rowHeight = UITableViewAutomaticDimension
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
and
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as CustomTableViewCell
// Configure the cell...
let restaurant = restaurants[indexPath.row]
cell.namelabel.text = restaurant.name
cell.locationlabel.text = restaurant.location
cell.typelabel.text = restaurant.type
cell.thumbnailImageView.image = UIImage(named: restaurant.image)
cell.thumbnailImageView.layer.cornerRadius = cell.thumbnailImageView.frame.size.width / 2
cell.thumbnailImageView.clipsToBounds = true
cell.accessoryType = restaurant.isVisited ? .Checkmark : .None
return cell
}
Thoughts on how to have the cells autoresize initially?
UPDATE: As of Xcode 7 beta 6 this is no longer an issue
Just call "reloadSections" after your Table is loaded:
self.tableView.reloadSections(NSIndexSet(indexesInRange: NSMakeRange(0, self.tableView.numberOfSections())), withRowAnimation: .None)
Or in Swift 3:
let range = Range(uncheckedBounds: (lower: 0, upper: self.tableView.numberOfSections))
self.tableView.reloadSections(IndexSet(integersIn: range), with: .none)
I ran into the same issue and found out that the accessory cell.accessoryType messes with this automatic resizing when it is not None, so it seems like a bug in Xcode at the moment.
But as #Blankarsch mentioned, calling reloadSections(..) helps to fix this issue if you need to have an accessory.
I think the answers over here have fewer side effects. Specifically adding cell.layoutIfNeeded() in tableView:cellForRowAtIndexPath:
I'm also doing what #nosov suggests as is good practice, but haven't tested if they need to be done in tandem.
just override estimatedHeightForRowAtIndexPath like this
(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
and check your autoLayout constraints in CustomTableViewCell view.
Just make sure that your labels don't have an explicit content size set at Interface Builder. They must be Automatic like the screenshot below for the Automatic Row height to work properly without the need to reload any sections up front.
If you set your constraints based on the cell itself (instead of cell content view), the table is not able to get the proper size. So, to fix this issue, your constraints must be set to the content view.
However, this is problem when your cells supports both configuration with/without accessory view. In that case, the content view gets resized according to the accessory view, and the result may not the the expected by the user. So, in this case, a solution is setting 2 constraints, one to the cell and a second one with lower priority to the cell content view.
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath;
In the function set the cell with the preferred content, in order for UITableViewAutomaticDimension to work flawlessly.
The problem is caused because the cell content is loaded in some other delegate function, so you can see that cells automatically resize to the required size.
Make sure to init your cell in tableView:cellForRowAt:. I've run into this issue even with Xcode 8 when I was setting cell content in tableView:willDisplay:forRowAt:
For me I only have this problem when using willDisplay cell to set the text of my labels
If I set the text of my labels in cellForRowAt index path, everything is fine
For me what solved it was the combination of #[David Hernandez] answer.
Removed the selection from above, and in Cell's layoutSubviews I set the preferredMaxLayoutWidth as this (change 30 to your desired left right spacing)
-(void) layoutSubviews {
[super layoutSubviews];
self.textDescriptionLabel.preferredMaxLayoutWidth = self.frame.size.width - 30;
}
Xcode 9.3, Swift 4.1
adding
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
in addition to
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
worked for me.

SelectedBackgroundView of UICollectionViewCell visible when it should not be

I've got a UICollectionView. With some cells inside with a white background color. I've set the selectedBackgroundView to a basic purple view.
My CollectionView has a constraint with a height of 0 and when I hit a button I update the constraint to 80. When I'm doing that, during the animation i can see the purple background on the screen until the end on the animation and i cannot understand why or how prevent this ?
Everything else working fine, it's just a "visual" bug.
Any suggestion about how to fix this ?
Gif of the bug where you can see the purple appearing during the animation
Here is my cell construction if it can be of any help :
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell = collectionView.dequeueReusableCellWithReuseIdentifier("WidgetMenuCellIdentifier", forIndexPath: indexPath) as UICollectionViewCell
cell.removeSubviews()
// some code setup
cell.selectedBackgroundView = UIView()
cell.selectedBackgroundView.backgroundColor = UIColor.purpleColor()
return cell
}
Subclass your UICollectionViewCell
Do
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
// your code
cell.selectedBackgroundView.hidden = true
return cell
}
Then in your subclass :
override var selected:Bool {
willSet {
self.selectedBackgroundView.hidden = false
}
}
It should work.
It seems like this code is being executed within an animation, causing unexpected behavior at times based on how various properties animate. Another complicating factor is that, because cells are reused, it won't reproduce if a reused cell is already configured correctly (i.e. there is nothing to animate). Adding the following after styling the selectedBackgroundView was the least hacky solution I could think of.
[cell.selectedBackgroundView.layer removeAllAnimations];
Depending on what your cells are like you may also want to consider removing animations on other layers as well. For example:
[cell.backgroundView.layer removeAllAnimations];

Resources