I quite like the way that padding has been added to the UITableViewCells in this app. I doubt it's possible in Storyboard, but what's the best way to achieve this?
You could easily do this in storyboard I think.
Just add a custom cell, grey background.
On that add a UIView as a subview, with a white background, and arrange the size so that it becomes a smaller rectangle inside your cell, so it gets this margin effect.
Then add your labels/imageviews on that white subview and you're good.
Anything wrong with that approach?
Feels a bit like cheating, but why not?
Using Storyboard this can be a daunting layout to achieve with UITableView on iOS 7. Programmatically it can be done fairly easily, with a bit of patience.
Anyway, given the quantity of information in the cell, I'd be tempted to use a UICollectionView with a UICollectionViewFlowLayout instead of a table. This might make things easier for you as you can set the cells size, sections margin, minimum distance between items, etc. all within Storyboard.
All you need is to make custom table cell and add specific background
#implementation CustomTableViewCell
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
<init your custom cell here>
UIView *bgView = [[UIView alloc] initWithFrame:self.bounds];
CGRect whiteRect = CGRectInset(bgView.bounds, 10, 5);
UIView *innerView = [[UIView alloc] initWithFrame:whiteRect];
innerView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
innerView.backgroundColor = [UIColor whiteColor];
[bgView addSubview:innerView];
bgView.backgroundColor = [UIColor colorWithRed:225.0/255 green:224.0/255 blue:230.0/255 alpha:1.0];
self.backgroundView = bgView;
}
return self;
}
Also here you can add self.selectedBackgroundView = selectedView in the same way to assign the specific view to your cell while it is highlighted/selected.
Related
I'm facing a problem with UITableView and it's property tableHeaderView.
I want to have the tableHeaderView to behave like UISearchBar, i.e. the content offset should be the of tableHeaderView.
Setting contentOffset, etc. didn't help when the table view wouldn't fill the view's frame.
Here's a screenshot of the current behavior:
(source: tubtub.de)
And how I'd like it to have:
(source: tubtub.de)
I'm inserting the headerView in viewDidLoad as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
headerView.backgroundColor = [UIColor redColor];
self.tableView.tableHeaderView = headerView;
}
Any help or hint is highly appreciated. Thanks!
EDIT: I made it working by utilizing UIScrollViewDelegate and subclassing UITableView. Check it out on the github repo provided.
You can use setContentOffset: by headerView height.
This contentOffset will only happen when you have enough number of data to be off by your headerView height. i.e) If tableView is not scrollable because you have only few data like one in your screenshot, the headerView is still visible. However if you have lots of number of data that can't not be displayed in the screen it will have contentOffset.
Try this with 20 rows. You will see what I mean.
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
headerView.backgroundColor = [UIColor redColor];
self.tableView.tableHeaderView = headerView;
[self.tableView setContentOffset:CGPointMake(0, 44)];
With only 3 rows, this contentOffset won't work and it might be desired behavior in your case because you don't want to hide the searchBar when you have extra space to display.
I came up with implementing my own solution.
I utilize UIScrollViewDelegate and came up with a subclass of UITableView for calculating the contentSize dynamically.
Take a look at the github repo here.
I would double check the frame for the table itself. By setting the headerView's frame to start at 0,0, you are specifying that it should have its origin in the top left of the the view that is designated for the table.
is it possible to make a distance between cells like that in standard UITableView? There is no options to make separator bigger. Also this distance from right and left.
you can do this by set your cell background to whatever background you want (let's say gray in this case) and in the cell, add a white uiview with left, right, and bottom margin like this:
Then go to your table view, set the separator as none
and one last step, set the background of your table view to the same gray background as your cell.
Then you don't have to do anything particularly in your code besides simply initial your table cell based on the custom nib file (i assume you want to do this anyway).
If you prefer to construct your cell in codes, you can use the same logic.
in method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
cell.backgroundColor = [UIColor whiteColor];
// This will create a line of 3 pixels that will be separating the cells
UIView *separator = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,3)];
separator.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview: separator];
// and if you want the border do left and right add:
UIView *separatorRx = [[UIView alloc] initWithFrame:CGRectMake(318,0,2,cell.frame.size.height)];
separatorRx.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview: separatorRx];
UIView *separatorSx = [[UIView alloc] initWithFrame:CGRectMake(0,0,2,cell.frame.size.height)];
separatorSx.backgroundColor = [UIColor darkGrayColor];
[cell.contentView addSubview: separatorSx];
return cell;
}
One way would be to set the backgroundView of the UITableViewCell to an UIImageView containing this white box on that gray background
You have to make a subclass of UITableViewCell. In your own subclass you may make everything you dream about! So, you need to add UIView with whiteColor background and margins as subview on your custom UITableViewCell.
There is not padding option in UITableView. You can either add a UIView in your UITableViewCell which will contains all the cell subviews, and change it's frame to create a padding right in the cell.
I suggest you to use UICollectionView instead, you can easily set the space between cells using a layout. If the cell is smaller than the actual collection View, then it's automatically centered.
How do I make the background for a tableHeaderView clear, but keep the rest of the UITableView background opaque?
I'm using a transparent tableHeaderView for a paralax effect. The object behind the tableView is a longer than the clear tableHeaderView "window" so I can center the visible data. This works well for longer lists as I can use the tableView as a mask, but when I don't have enough cells in the table the background object displays below the cells.
Relevant code:
self.tableView.backgroundView = nil;
self.tableView.backgroundColor = [UIColor whiteColor];
UIView *tableHeaderView = [[UIView alloc] initWithFrame: CGRectMake(0.0, 0.0, 320.0, 250.0)];
tableHeaderView.backgroundColor = [UIColor clearColor];
self.tableView.tableHeaderView = tableHeaderView;
I've tried setting a background color for the tableView, but that makes the whole UITableView opaque (including the tableHeaderView), removing the "window" I have at the top.
Any ideas on how I can keep my transparent tableHeaderView while setting the body of the UITableView opaque?
Thanks!
After a couple days I was able to figure it out. The premise of the solution is to add a subview to the backgroundView of your table and change the subview's frame as you scroll.
The relevant code in viewDidLoad:
...
// Create the UIView that will become the tableView backgroundView
UIView *tableViewBackground = [[UIView alloc] initWithFrame:self.tableView.frame];
tableViewBackground.backgroundColor = [UIColor clearColor];
// Create the opaque backgroundView and set the frame so that it starts below the headerView
partialBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 250, 320.0, self.view.frame.size.height)];
partialBackgroundView.backgroundColor = [UIColor redColor];
// Add the partial background to the main background view and apply it to the tableView
[tableViewBackground addSubview:solidTableBodyBackgroundView];
self.tableView.backgroundView = tableViewBackground;
...
And then as you scroll, you can update the "visible window" in scrollViewDidScroll:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat scrollOffset = scrollView.contentOffset.y;
partialBackgroundView.frame = CGRectMake(0, 250 - scrollOffset, 320, self.view.frame.size.height);
// Other parallax code for scrolling
}
There may be better ways of doing this, but I found this to be pretty simple and it worked well.
A simpler way of doing the accepted answer for multiple sections
// Set the view for each cell with a clear color
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, SectionHeaderHeight)]; //
view.backgroundColor = [UIColor clearColor];
return view;
}
// Set the height of your desired header
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 10;
}
Here's a super late but quick and simple answer to this if like me you're returning a subclass of UITableViewHeaderFooterView as header view in your viewForHeaderInSection delegate method.
Setting myHeaderView.backgroundColor = UIColor.clear not helping you?
Try setting myHeaderView.layer.backgroundColor = UIColor.clear.cgColor instead.
Unless I'm misunderstanding something, you should be able to do this in two steps:
You will need to make the cells in your table opaque. Leave the tableView's background color set to [UIColor clearColor], and same goes for the views for your table header (and section headers if that applies).
Then take your table footer view (tableFooterView property of the UITableView), make it opaque, and make it very tall. When you only have a few cells in the table, the table footer will take up the rest of the screen.
Again, I might be misunderstanding something, but give that a go and see what you get. Good luck!
Swift-5, Transparent Section Header
Add a view and set its background as transparent
then return this view in ViewForSectionHeader method in tableView
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return viewForSection
}
I have a tableView with a textField and a textView in two cells. Thats it.
and I added them in tableView:cellForRowAtIndexPath:.
I can't edit the content!
Probably the touch is not passing through to the text field and the textView.
All the solutions are asking me to use a xib with a custom cell class.
So do I have to create two new classes for a two-row tableView ?
Cant I just get away by adding these as subviews to normal cell's contentView ?
Secondly, If using tableView for that kind of layout is overkill,
What is the alternatve where I need a textView below a textArea in a rectangular border with rounded corners and a separator between them with plain UIViews ?
You don't need to go as far as creating 2 new classes. Adding them will do just fine, maybe even keeping a reference in your controller.
Check for userInteractionEnabled on your UITableView, UITableViewCell, and your UITextField and UITextView. If you disable the user interaction for a view, every subview will have it's user interaction disabled as well. If you want to disable a row's selection, just set cell.selectionStyle = UITableViewCellSelectionStyleNone;
You don't need a xib to subclass UITableViewCell. In this case, adding to the content view should be fine, and a subclass would not be necessary. It does also sound like you do not need a table view. A reason you might want one is if you would ever need more of these cells, otherwise a regular view controller might be more appropriate and easier to implement.
I use Core Graphics to create rounded corners on UIView objects and even add shadow effects, but there is a bit of a learning curve. You could start by searching the Internet for UIView rounded corners.
Try to use this code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0){
UITextField *customField = [[UITextField alloc] initWithFrame:CGRectMake(60.0f, 10.0f, 400.0f, 60.0f)]
customField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
customField.delegate = self;
customField.adjustsFontSizeToFitWidth = NO;
customField.borderStyle = UITextBorderStyleNone;
customField.autocapitalizationType = UITextAutocapitalizationTypeNone;
customField.autocorrectionType = UITextAutocorrectionTypeNo;
customField.enablesReturnKeyAutomatically = YES;
customField.returnKeyType = UIReturnKeyDefault;
customField.keyboardType = UIKeyboardTypeDefault;
[cell addSubview:customField];
}
if (indexPath.row == 1){
UITextView *notes = [[UITextView alloc] init];
notes.editable = YES;
notes.font = DEFAULT_FONT(16);
notes.text = infoNotesStr.text;
notes.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
notes.backgroundColor = [UIColor blueColor];
notes.delegate = self;
CALayer *layers = notes.layer;
layers.cornerRadius = 10.0f;
[cell addSubview:notes];
}
}
I want to display a double bordered like following image...
The border has a dark color (magenta) and a light color (white) (not the actual colors).
I have created a custom .xib file and a custom class extending UITableViewCell for my table view cells.
self.tableView.separatorColor = [UIColor whiteColor];
Then in the custom table view class, I did this...
- (void)awakeFromNib
{
[super awakeFromNib];
UIView *cellBottom = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height, self.bounds.size.width, 1.0f)];
cellBottom.backgroundColor = [UIColor magentaColor]; //
[self addSubview:cellBottomView];
// ... other code
}
I got the following result... there seems to be some gap between backgroundColor and separatorColor.
Why is this happening? The height of UIView has been set to 1 and is positioned at the bottom of UIView as well.
If there is some better solution to this could somebody throw some light on that?
Michal Zygar is partially correct.
Make sure your -(NSInteger)tableView:(UITableView*) heightForRowAtIndexPath:(NSIndexPath*) is correctly set to the height of the view. It doesn't automatically do that for you.
The other tip I would suggest as I do it myself, is to NOT use separators. Set your separator to none, and then add in two 1px-heigh views at the top and bottom of the cell in the XIB file.
Make sure to set the autosizing for the bottom two to stick only to the bottom edge, just in case you want to change the cell's height!