I cannot convince UITableViewCell to display under another view as per the attached image. It happens when I embed UITableView into UIViewController.
VoucherTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"VoucherTableViewCell" forIndexPath:indexPath];
if (cell == nil) {
cell = [[VoucherTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"VoucherTableViewCell"];
}
Image one is before scrolling up.
Image two is the problem.
just try in viewDidLoad this code
self.edgesForExtendedLayout = UIRectEdgeNone;
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, yourTopiew.height, 0);
Follow these steps...
1. Make sure you are using correct Size class for iPhone.
2. Remove your tableView constraints if any.
3. Position your tableView correctly. (Bottom of your buttons)
4. Add top,bottom, left, right constraint to tableView.
5. Also make sure your buttons have correct constraints.
The problem is with the frame and positioning of your table view.
First the table view is places above the buttons in the view hierarchy in you nib file.
Second you need to set the frame and constraints of the tableview as such that it starts right from where the buttons end.
Related
I have different examples where we can update the UITableViewCell height based on growing UITextView which actually is working for me. The issue which I am facing is, I have more subviews below UITextView inside a UITableViewCell. This way, the cell's height updates but the position of the subviews remain fixed which causes overlap of UITextView and the subviews.
Just to mention, I am not using auto layout.
How do I fix this ?
These are the three screenshots which will help in understanding my issue :
1. Before TextView is shown :
2. After TextView is shown :
3. After text is entered :
I'm assuming you are using auto layout for this cell (but we could use a code example or Xcode screenshot to help you more specifically). If you are using auto layout, you'll want to make sure that:
You have a constraint between the UITextView and the other UIView subviews below it in the cell
The other UIView subviews are eventually constrained to the bottom of the cell.
Because UITableViewCells are reused, you will find that when adding objects to the contentView, those objects will also be reused without being removed, leading to overlapping subviews. The way around this it to start your cellForRowAtIndexPath with the following code:
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
for (UIView * view in [cell.contentView subviews]) {
// clears the cell before reusing
[view removeFromSuperview];
}
Hope this helps.
Are you using auto layout? I have done this before several times with UITableViewCells though it’s mainly been with UILabel and not UITextView.
Your problem might be resolved with auto layout. You layout all your subviews (inside of UITableViewCell) relative to each other. If one view (i.e. UITextView) changes size the other views will then adjust relative to that view. Here are a few useful links.
This isn’t specific to UITableViewCell but has a lot of good examples of various scenarios.
Stanford University Developing iOS 7 Apps: Lecture 9 - Animation and Autolayout
https://www.youtube.com/watch?v=r1sc7NI6-wo
I change the frame of cells (add margins to the left and to the right) according to the code. The problem is cells update their frames only after they disappear and appear again via scrolling. I used table view's - reloadData as well, but it did't help. How do I force cells to be redrawn without scrolling?
- (UITableViewCell *) tableView: (UITableView *) tableView
cellForRowAtIndexPath: (NSIndexPath *) indexPath {
PersonTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: #"TableViewCellID"
forIndexPath: indexPath];
cell.frame = CGRectMake(20, cell.frame.origin.y, cell.frame.size.width-2*20, cell.frame.size.height);
/* tried any of those
[cell setNeedsDisplay];
[cell setNeedsLayout];
[cell layoutIfNeeded];
*/
return cell;
}
I'd recommend using .xibs for this. Much easier.
As far as I know, you are not able to change the frame of a cell in that manner. The cell's height is determined by heightForRowAtIndexPath, and the width is set to the width of the tableView.
You may be able to do it in some manner the way you are attempting, but the cleanest way I know is the following.
If you want there to be a margin around the cell, you can:
Create a nib for a UITableViewCell with a UIView containing all your views, and place a border using constraints.
Embed all your content inside a UIView (lets call this borderedContentView) and place this as the immediate subview of contentView
Place constraints relating borderedContentView to the contentView, with the leading, trailing, top and bottom constraints set to the values that create the border width you desire.
If your tableView has a backgroundColor, you'll have to set the contentView's backgroundColor to the same color as the tableView's backgroundColor so as to create the illusion of a margin. Do this in the tableView's delegate method willDisplayCell: or in a subclass of UITableViewCell awakeFromNib or other related method.
Bask in the glory of your margined cells.
You can also do this programmatically if you prefer not to use interface builder, but it is very easy to do in IB.
Hope this helps.
The solution to the problem is to override setFrame method of UITableViewCell. This way it perfectly works.
i have some strange Problem. I use the Interface Builder to create a Custom TableCell with three Labels and one UIImageView:
I want that the Cell has a little space to the TableView (the blue border), so i put an extra View inside the Cell. As you can see the UIImageVIew is realy small and not higher than two labels, but when i run my code on the device the UIImageView is high as the white View and even covers the Label a little bit. The only thing i do in my Code is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"CustomCellReuseID";
GTEventCustomCell *eventCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (eventCell == nil) {
eventCell = [[GTEventCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1];
}
// Configure the cell...
[eventCell.imageView setImage:[UIImage imageNamed:#"heart.png"]];
.
.
.
What´s wrong?
This will fix your problem:
eventCell.imageView.contentMode = UIViewContentModeScaleAspectFit;
I hope you have not missed the auto layout constraints for the objects inside the custom cell.
If not select a label/view
in toolbar Editor > Resolve Auto Layout issues > add missing constraints
and change the auto layout constraint as you need it.
I just think you should change your properties in the right panel.
You can also desactivate autolayout constraints and, to be sur to place your items at the good place, set them programmatically.
example :
at the top of your file :
#define X_Cell_Padding 10
#define Y_Cell_Padding 10
in cellForRow methods :
[[cell yourImageView] setFrame : CGRectMake(X_Cell_Padding, Y_Cell_Padding, yourImageView.frame.size.width, yourImageView.frame.size.height)];
don't forget to create a custom cell class with your IBOutlet yourImageView and to set this class for the cell in your storyboard / xib
I'm creating a mail screen using which visually resembles the iOS native email app. It looks like this (Both images are of the same screen. First one is the top half and the second one is the rest of it).
The difference is my mail screen has more custom fields in addition to normal To, Cc, Subjet fields.
I'm using a UITableViewController to create this. Below is a code snippet which creates a cell (For each cell it's pretty much the same).
- (UITableViewCell *)tokenTableView:(TITokenTableViewController *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
self.tableView.frame = CGRectMake(0,0,320,320);
UIView *contentSubview = nil;
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifierSubject];
if(!self.txtSubject) {
self.txtSubject = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
self.txtSubject.frame = CGRectMake(10, cell.frame.size.height / 2 - self.txtSubject.font.lineHeight / 2, tableView.tableView.bounds.size.width, 30);
self.txtSubject.placeholder = #"Subject";
[self setupMailData:indexPath.row];
}
contentSubview = self.txtSubject;
}
Say, I open up a draft. All the details in the input fields are filled and without changing anything, I hit send and it crashes the app. I know what's causing this. The problem is that normally the cells that are under the viewable portion of the screen gets created as you scroll down, right? But in this scenario, if I send it without scrolling down but those cells below the viewport don't exist thus it throws the error.
If I open the draft, scroll down and hit send, it works fine.
I need to know if there's a way to create all these cells at once. Even the cells that are below the viewport at first. Not depending on the user to scroll down.
I hope you have an idea about my situation. Can anyone suggest a solution?
Thank you.
follow steps:
Take uiscrollview and set scrollview frame as which you want to display.
Take uitableview as a subview of uiscrollview
set property Scrolling Enabled = NO (uncheck checkbox in .xib) of uitableview
call reloaddata method of uitableview
set tableview frame and contentsize of scrollview
tblEmail.frame = CGRectMake(yourXPos, yourYPos, yourWidth, tblEmail.contentSize.height);
scrollObj.contentSize = CGSizeMake(yourScrollWidth,tblEmail.contentSize.height+10);
so, the height of tableview is equal its contentsize. so, its create all cells at a time. and set contentsize of scrollview is equal tableview contentsize. so, the scrolling feature is worked like uitableview scrolling...
Use a Storyboard, add a UITableViewController and set the 'Content' to StaticCells.
Then you can define all the cells and their content in the Storyboard. You can even wire stuff up to IBOutlets in your UITableViewController subclass and they will all be there for you when viewDidLoad is fired ...
When using a Storyboard your code for getting the ViewController looks like:
[[UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil] instantiateInitialViewController];
In the following code, if we do [cell addSubview: someLabel] vs [cell.contentView addSubview: someLabel], they seem to work the same. Is there any difference doing one or the other? (the custom cell in the real code is adding UIImageView and UILabel) (UIView, on the other hand, doesn't have contentView, so we don't need to add subview to its contentView. UITableViewCell is a subclass of UIView by the way)
-(UITableViewCell *) tableView:(UITableView *) tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
if ([tableView isEqual:self.songsTableView]){
static NSString *TableViewCellIdentifier = #"MyCells";
cell = [tableView dequeueReusableCellWithIdentifier:TableViewCellIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:TableViewCellIdentifier];
}
// ... some code to create a UILabel (not shown here)
[cell addSubview: someLabel]; // vs using [cell.contentView addSubView: ...]
I believe If I am not wrong, the contentView is a subview of UITableViewCell.
If you look at this page here, you can see there are actually 3 subviews in a UITableViewCell
I think by default, the Editing Control is hidden until you enter edit mode for a table in which case, the Editing Control appears (the minus button left of each row) and your contentView gets resized and pushed to the right. This is probably what gives the "proper animation" effect mentioned by the other answer.
To test the difference, try adding a subview such as UILabel with text, to the cell rather than the cell.contentView. When you add it to cell rather than cell.contentView and you enter edit mode for your table, I believe your UILabel will not resize, you will see the edit button ontop/below the minus sign button.
Placing your views in the contentView affects proper animation in and out of edit mode. Place all of your subviews in contentView when you're not subclassing, which should be all of the time unless you know what you're doing.