Hi! I'm working with an UITableView, with UITableViewCell.
The UITableViewCell has inside an UIWebView (because i'm using entities, bold text, ecc...).
The webview is loaded with this code:
UIWebView *testoLabel2 = (UIWebView*)[cell viewWithTag:3];
NSString *html = [NSString stringWithFormat:#"<html><font size=2>%#</font></body></html>", sottotitolo];
testoLabel2.opaque = NO;
testoLabel2.backgroundColor = [UIColor clearColor];
[testoLabel2 loadHTMLString:html baseURL:nil];
What's the problem?
That when i need to reload the data (for example after the change of the deviceOrientation) using
[my_table reloadData];
all the webView blink!
For just a second, but they blink! And it's a very ugly effect!
Do you know why?
Thanks!
EDIT: also if i scroll down the tableview, when i scroll up the webview that before were loaded are white! But just for a moment, after they load the text!
Not sure exactly why but it's good practice to set all view backgrounds in cells to a solid solid color. The flash could be the cell rendering it's background and then the web view on top of it. If you set the webview background to your desired color and leave it opaque then this shouldn't happen. Good luck!
Related
this is the repo i made.
https://github.com/lifesaglitch/UIWebViewFlashWhite
The basic idea is:
I have an expandable table view, with 2 cells: header cell and content cell.
when click on header cell, I insert a content cell, and load a html string to the web view, which is a subview of the content cell.
If it's the first time I expand a cell, the web view has a white flash, with the correct frame size. There may be flash as well for the subsequent expand, but the frame size is wrong.
what I have tried (in the project) is to set the color to clear, which does not work. I also tried a webview's delegate, set hidden = NO after the html string was loaded, but sometimes the delegate call back is not called. Maybe it's because the reusable mechanism.
Please download my project from above link and try it out.
Here are some sample code:
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.contentView.backgroundColor = [UIColor clearColor];
}
return self;
}
data source method:
ContentCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ContentCell"];
[cell.contentView loadHTMLString:#"<html><body style='background-color: #ff0000'>this is contentasdoifjoiwjeofiqjweoifjqopweifj </body></html>" baseURL:nil];
EDIT:
I have committed a new version: use placeholder to hide the webview first, and unhide it when it's loaded, but there is still white flash screen.
First, you need to modify your expand/collapse animation to HeaderView like Apple sample
or this tutorial
Then, you need to modify your code in ContentCell.h and ContentCell.m
Don't hook up contentView property with other IBOutlet, your view
after drag to tableCell will be a subView of it. SupperView and
Subview have same name can cause crash.Choose cellWebView name and hook up with your UIWebView:
- (void)awakeFromNib{
self.backgroundColor = [UIColor clearColor];
[self.contentView setBackgroundColor:[UIColor clearColor]];
[self.cellWebView setOpaque:NO];//Need to clear background of UIWebView
self.cellWebView.backgroundColor = [UIColor clearColor];
}
I have a table view which flips back and forth between view mode and edit mode. I have one cell which I would like to be transparent in view mode, and look like a "normal" cell in edit mode (i.e. white background, rounded rectangle outline). Basically, the same thing you see the name cell do in the contacts app as you switch in & out of edit mode.
I used the solution in How to create a UITableViewCell with a transparent background to get a transparent background, but I can't figure out how to get the original background back.
Currently, I create two background views in viewDidLoad:
nameCellDefaultBackview = [[UIView alloc] initWithFrame:CGRectZero];
nameCellDefaultBackview.backgroundColor = [UIColor clearColor];
nameCellEditBackview = [[UIView alloc] initWithFrame:CGRectZero];
nameCellEditBackview.backgroundColor = [UIColor whiteColor];
I then give my cell the default background view:
nameCell.backgroundView = nameCellDefaultBackview;
In setEditing:animated: I set the background of the cell depending on the editing mode:
if (editing) {
nameCell.backgroundView = nameCellEditBackview;
} else {
nameCell.backgroundView = nameCellDefaultBackview;
}
The problem is, in editing mode I get a white rectangle instead of something that looks like a cell - which is precisely what I asked for, but not what I want :). I've tried a couple of other things, like setting backgroundView to nil (which seems to = no change), and saving the 'initial' background view in viewDidLoad (that didn't seem to work, and looking in the debugger the variable was 0x0 when I tried to assign it to the cell in setEditing).
So what I want is to look like this in normal mode:
And like this in edit mode:
But what I currently get in edit mode is:
So how do I get the white background/border/rounded corners back?
If you want to use back the original cell in edit mode, you should consider showing and hiding the cell instead of setting the background view. The background view is added as a subview behind all other views, thus, setting it to transparent has no effect. Reference: Apple Doc.
To hide or show a table cell, see this post
for editing mode, dont set the backgroundView. Just call [tableView reloadData] when you enter editing mode and set the backgroundView in cellForRowAtIndexPath like this:
if (!editing) {
nameCell.backgroundView = nameCellDefaultBackview;
}
//if it is editing, then it will take the default style.
hope this helps.
I've decided to change my approach a bit, and this is now working:
Instead of trying to show/hide the background of one cell, I now have two cells:
IBOutlet UITableViewCell *nameCellViewMode;
IBOutlet UITableViewCell *nameCellEditMode;
In viewDidLoad: I change the background of nameCellViewMode to make it transparent:
UIView *clearBackgroundView = [[UIView alloc] initWithFrame:CGRectZero];
clearBackgroundView.backgroundColor = [UIColor clearColor];
nameCellViewMode.backgroundView = clearBackgroundView;
In following with KDaker's suggestion I now just do a tableView reloadData in setEditing:animated:, and then in cellForRowAtIndexPath I do this:
if (self.editing)
{
return nameCellEditMode;
}
else
{
return nameCellViewMode;
}
My app's main view has a uiwebview. It is white for a split second before it has time to render the HTML the app generates.
Is there a way to make the uiwebview black, or another color, before it renders? The flash of white isn't part of my plan for a smooth visual transition.
Objective-C or MonoTouch answers are fine, I am bi-lingual.
Another thing to try is to make the view transparent:
webView.backgroundColor = [UIColor clearColor];
webView.opaque = NO;
This causes additional compositing work, however, so you can reset these values to something more friendly for that after your web view loads, in webViewDidFinishLoad:.
- (void) webViewDidFinishLoad:(UIWebView *)webView
{
webView.backgroundColor = [UIColor blackColor];
webView.opaque = YES;
}
One thing you can try is put a UIView with the color you want and position it above the UIWebView with the same width and height. Then in the webViewDidFinishLoad method, set the UIView to hidden.
I can't comment yet hence the answer.
#Steve, actually it's possible to do with storyboards.
Place a UIView under the UIWebView and:
// Can be set in the storyboard
bottomView.backgroundColor = [UIColor yellowColor];
webview.alpha = 0;
Keep in mind that a lot of page fetch stuff after being loaded via JS so you still can be left with a white page couple seconds after
- (void) webViewDidFinishLoad:(UIWebView *)webView
{
webView.alpha = 1;
}
To add to Steve Madsen's answer (since I can't comment yet). If you instanced the UIWebView in Interface Builder, you wont be able to set alpha to 0.0, but what you can do is bring up the color picker to set a background color (white, black, gray, it doesnt matter), then set the opacity of that color to zero percent, and that works.
Apple's iPhone apps such as Music and Contants use a search bar in a UITableView. When you scroll down so that the search bar moves down, the empty space above the scroll view's contents has a light gray background color (see screenshot).
(Notice that the search bar has a slightly darker edge line at its top. This is not there for the default UISearchBar, but subclassing should take care of that.)
I tried setting the background color of the UITableView, but that affects the rows as well. Does anyone know how to achieve this effect? Am I going to have to override implement drawRect: or is there a built in way?
Setting transparencies is bad for performance. What you want is the gray area above the search bar, but it should still be white beyond the end of the list.
You can add a subview to your UITableView that lives above the content instead.
CGRect frame = self.list.bounds;
frame.origin.y = -frame.size.height;
UIView* grayView = [[UIView alloc] initWithFrame:frame];
grayView.backgroundColor = [UIColor grayColor];
[self.listView addSubview:grayView];
[grayView release];
You could add more fancy stuff to the view if you like, perhaps a fade, or a divider line without subclassing UISearchBar.
This is one of my very favorite tricks.
UIView *topview = [[[UIView alloc] initWithFrame:CGRectMake(0,-480,320,480)] autorelease];
topview.backgroundColor = [UIColor colorWithRed:226.0/255.0 green:231.0/255.0 blue:238.0/255.0 alpha:1];
[self.tableView addSubview:topview];
Basically you're creating a big view the size of the screen and placing it "above" the content area. You'll never be able to scroll up past it.
And don't worry about the memory impact of a UIView that's 320x480 pixels, it won't consume any significant memory because the CALayer doesn't have any meaningful content.
NOTE: Why is this answer relevant when the "accepted" answer is so much simpler? Why not just set the backgroundView on the table view? It's because, in the case of the Contacts app as shown in the original question, the area "above" the table view has a different background color (light blue) than the area "below" the table view (white). This technique allows you to have two different colors above and below the table view, which cannot be accomplished by a simple background.
EDIT 1/2018: As Tom in the comments pointed out, this answer is quite old and assumes that all iOS devices have the same screen size (seems crazy but it was the case in 2009 when I answered this). The concept I present here still works, but you should use UIScreen.main.bounds to figure out the actual screen size, or you could get into some fancy auto layout stuff (suggestions welcome). I don't recommend using tableView.bounds as in another answer, because typically in viewDidLoad the size of your views is not necessarily the size that they will become after the controller resizes them. Sometimes they start out as 0x0!
To extend on HusseinB's suggestion:
Swift 3
let bgView = UIView()
bgView.backgroundColor = UIColor.white
self.tableView.backgroundView = bgView
Objective C
UIView *bgView = [UIView new];
bgView.backgroundColor = [UIColor whiteColor];
[self.tableView setBackgroundView:bgView];
As of iOS 7, you can tinker this by changing the tableview background view.
[self.tableView setBackgroundView:view];
make the view's background colour the same as your parent view colour.
This code works in Swift fot UITableView:
var frame = self.tableView.bounds
frame.origin.y = -frame.size.height
frame.size.height = frame.size.height
frame.size.width = UIScreen.mainScreen().bounds.size.width
let blueView = UIView(frame: frame)
blueView.backgroundColor = UIColor.headerBlueColor()
self.tableView.addSubview(blueView)
In Swift (tested on iOS9)
let backView = UIView(frame: self.tableView.bounds)
backView.backgroundColor = UIColor.clearColor() // or whatever color
self.tableView.backgroundView = backView
EASIEST SOLUTION
The easiest way to create different colors in the bottom and in the top of a bouncing area of a table view is to set the key tableHeaderBackgroundColor of the table view. Doing this way you set the top color. I'm not sure, but maybe there is another key for the footer, take a look. If you don't find anything, you just have to set the background of the table view with the color that you want to show in the bottom. Above you can see an example code:
self.table.setValue(UIColor.blue , forKey: "tableHeaderBackgroundColor")
Hope it help you. If yes, let other people know about this easy way giving an up in the answer :)
I've only found one way to do this. You have to set the backgroundColor of the UITableView to be transparent, set the backgroundColor of the cell's contentView to whatever colour you want the actual cells to be, then crucially you have to get the light grey colour to appear behind the UITableView. That last step you can do by either setting the backgroundColour of the UIWindow, or of whatever is containing or your tableViewController.
So, assuming you have a view controller that is derived from UITableViewController, insert these lines in the -(void)viewDidLoad method:-
// sets the background of the table to be transparent
self.tableView.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.0];
// assuming we are inside a navigation or tab controller, set the background
self.parentViewController.view.backgroundColor = [UIColor lightGrayColor];
Then inside the part of tableView:cellForRowAtIndexPath: that creates new cells, add:-
// set an opaque background for the cells
cell.contentView.backgroundColor = [UIColor whiteColor];
I just encountered this issue myself and found a solution.
Cause
I used Spark Inspector to examine the layout of the table view - which really helped.
Thing is, that in this scenario the UITableView has 3 subviews:
UITableViewWrapperView
UIView - With backgroundColor set to light gray color
UISearchBar
While you swipe the tableview content downwards, the second subview height is dynamically increasing to fill the space between the UITableViewWrapperView and the UITableView frame origin.
Solution
Setting the backgroundColor or backgroundView property won't effect the 2nd subview.
What you need to do is find the second view and change its color, like so:
if (_tableView.subviews.count > 1) {
_tableView.subviews[1].backgroundColor = THE_TARGET_COLOR;
}
In my case I needed all views to be white so I used the following which is less prone to future changes of UITableView view hierarchy by Apple:
for (UIView *subview in _tableView.subviews) {
subview.backgroundColor = [UIColor whiteColor];
}
I will give you the best way to do this.
First set the background color of the table view to the one you want in interface builder.
Then respond to the UITableView delegate tableView:willDisplayCell:ForIndexPath: method
like this
- (void)tableView:(UITableView*)tableView willDisplayCell:(UITableViewCelll*)cell forIndexPath:(NSINdexPath*)indexPath
{
[cell setBackgroundColor:[UIColor whiteColor]];
}
Another Method is :
in ViewDidLoad method (or anywhere you like) set the tableView background color to clear color like this:
self.tableView.backgroundColor = [UIColor clearColor];
and then set the superview color to white
self.tableView.superview.backgroundColor = [UIColor whiteColor];
I don't think you want to override drawRect. Most likely what you're seeing is the background colour of another view or the window, which lies "behind" (i.e. is a superview of) the table view. There's usually a fairly complex layers of UIViews in Apple's UI widgets. Explore the view hierarchy in GDB, look at [myView superview] and then [someSuperView subviews] and try manipulating their BG colours in the debugger to see if you can find which one it is. However, if you implement a fix this way, be warned that it may not be future compatible.
You might also try setting the BG colour of one of the views behind the tableview in Interface Builder (or of the window itself).
If you are using a tableviewcell, you can set the view background to be opaque white. Then use
self.tableView.backgroundColor = [UIColor grayColor];
in the view did load method.
I'm sure that that is [UITableView backgroundColor].
You have affected rows, because rows have backgroundColor == clear (or semi-transparent).
So, If you'll make rows non-trasparent, all will work fine.
This will be solution.
I followed the tip outlined by Peylow, for a UITableView, by simply adding a subview. My only change from the code was to grab a color a bit closer to the one used in Apple apps, plus I got it a bit closer to Apple's look of having a line above the UISearchbar by reducing the frame origin y coordinate by one pixel:
frame.origin.y = -frame.size.height - 1
For anyone who's wondering how to do the same for the bottom bounce area:
First add a subview with your desired background color to your table view's background view:
self.bottomView = [[UIView alloc] initWithFrame:CGRectOffset(self.tableView.frame, 0, self.tableView.frame.size.height)];
self.bottomView.backgroundColor = whateverColorYouLike;
[self.tableView.backgroundView addSubview:self.bottomView];
And then in your table view's delegate:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect frame = self.bottomView.frame;
frame.origin.y = self.tableView.contentSize.height - self.tableView.contentOffset.y;
self.bottomView.frame = frame;
}
In my case the solution was to create a headerview for the table and assign a color, it solved the black background in bounce area in my apps when in dark mode. I did the same to its tableFooterView.
table.tableHeaderView = UIView()
table.tableHeaderView!.backgroundColor = UIColor.white
How can I set the background of UITableView (the tableview style is "Grouped") to use an image?
In newer versions of the SDK, you'll need to set tableView.backgroundView if you want it to be transparent, try something like this:
tableView.backgroundColor = [UIColor clearColor];
tableView.opaque = NO;
tableView.backgroundView = nil;
We need to do something about that plain background. We're going to use a PNG image and display it behind the UITableView.
Prepare a PNG image. It should be either 320x460 (if you have the status bar visible in your app) or 320x480 (if you hide it).
Drag it into XCode into the Resources folder and add to your project
Load the NIB file containing your UITableView into Interface Builder
Open the library (Tools> Library), switch to the Media tab, and drag the image to the View, create a new UIImageView.
Use the inspector to move and resize the image so it's at X=0, Y=0, Width=320, Height=480
Put the UIImageView behind the UITableView (Layout > Send to Back)
Save, Build and Go!
Disappointingly, you won't be able to see your background. The UITableView's background is blocking us from seeing the UIImageView. There are three changes you need to make:
In the Attributes Inspector, make sure the UITableView's "opaque" checkbox is unchecked!
Set the UITableView's background color to transparent:
tableView.backgroundColor = [UIColor clearColor];
I hope this helps and solves your problem. It has worked for me and I have yet to find a more elegant way to display a background image for a UITableView.
The advantage of my solution, in comparison with setting a background image directly on the UITableView, is that you can indent the table's content. I often wanted to do this to just show two or three table cells at the bottom of the screen.
[tableView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"whatever.png"]]];
tableView.backgroundView = nil;
is enough. No need to set background color as Clear Color.
One way would be to make the table view transparent (set the view's background to 0% opacity) and place a UIImageView behind the UITableView. Remember that transparent tables and table cells will not perform as well as opaque ones.
In UI Builder the Background color has an "Other" choice.
This brings up a color picker.
The color picker has an opacity setting.
If you set the Opacity of the COLOR to 0 it works, can't speak to performance.
What I've found is that you have to use a "plain" styled table with a transparent background and then recreate the look of the rounded-corner cells by setting each cell's backgroundView to a UIImageView with a image that simulates the rounded look. This means that the top, bottom, and middle cells need different background images.
However, this does not address what happens when the user taps the cell and it goes "highlighted" - it will look squared off then. You can get around this by setting the highlighted image for your faked tablecell background image. You will also want to create your own disclosure accessory view (ImageView) with a white highlighted version. Then you can create a cell like this one I'm using (below). After I alloc one of these cells I then set the backgroundView and accessoryView to my UIImageViews.
#import "ClearBackRoundedTableCell.h"
#implementation ClearBackRoundedTableCell
- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]) {
}
return self;
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
if( [[self.accessoryView class] isSubclassOfClass:[UIImageView class]] )
((UIImageView *)self.accessoryView).highlighted = highlighted;
if( [[self.backgroundView class] isSubclassOfClass:[UIImageView class]] )
((UIImageView *)self.backgroundView).highlighted = highlighted;
self.textLabel.highlighted = highlighted;
}
#end
One note if you go this route: the cells in a grouped table are typically 300 px wide (in portrait mode) but your plain table here would need to be 302 wide to allow for the grey line on each side of the table, which is normally outside of the "content" of the table cell.
After spending a while with color picker, I found out that you need to specify opaque background not for the table view cell xib, but for the Table View where the cells will be located, which is another xib. From what I have seen, table view cell background attributes have no visual effect.
try this one
UIView *backView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
backView.backgroundColor = [UIColor clearColor];
cell.backgroundView = backView;
It worked for me in grouped tableview.
Make UITableview background as clear color.
Programmatically you can do it like this if your image is added into your resources:
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.opaque = NO;
UIImage *backroundImage = [UIImage imageNamed:#"my_backround"];
UIImageView *backroundImageView = [[UIImageView alloc] initWithImage:backroundImage];
Else you can do it in Interface Builder with this style :
You may need to configure the header files interface from UITableViewController to UIViewController and add <UITableViewDataSource,UITableViewDelegate> ,also don't forget to set the attributes of the tableview to not be opaque and reconnect the tableviews datasource and delegate outlets to the viewcontroller.