I have a viewController that has a tableView and a custom loading UIView that displays a loading message and spinner while the data of the tableView is being loaded.
The custom UIView has a red background that i can see, but i can still see the lines of the tableView, How can i get to display the custom uiview without seeing the tableView lines on the background.
#implementation LoadingView
#synthesize spinner;
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
// Initialization code
[self setUserInteractionEnabled:NO];
[self setBackgroundColor:[UIColor blueColor]];
// Spinner
spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[spinner setCenter:CGPointMake(320/2, 150)];
[self addSubview:spinner];
[spinner startAnimating];
//title label
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = #"Loading...";
titleLabel.font = [UIFont boldSystemFontOfSize:18];
titleLabel.lineBreakMode = UILineBreakModeWordWrap;
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.textColor = [UIColor blackColor];
titleLabel.textAlignment = UITextAlignmentLeft;
CGFloat height = [titleLabel.text sizeWithFont: titleLabel.font constrainedToSize: CGSizeMake(300, 1500) lineBreakMode: UILineBreakModeWordWrap].height;
[titleLabel setFrame: CGRectMake(120, 180, 100, height)];
[self addSubview:titleLabel];
[titleLabel release];
}
return self;
}
- (void)drawRect:(CGRect)rect {
}
- (void)dealloc {
[super dealloc];
[spinner release];
}
#end
You can set the lines "off", when you start you loading process, setting them transparent.
// Setting transparent
tableView.separatorColor = [UIColor clearColor];
And when you remove the loading UIView, you change the color for the one that you want.
// Setting the desired color
tableView.separatorColor = [UIColor grayColor];
Another alternative is to set the table view hidden while you don't have data to be displayed, and than when the first or more row appear you place you set the table view to not hidden.
I hope this will help you!
Cheers,
VFN
The problem was that self.view in the viewController had the tableView assigned directly. The solution is to assign the self.view a UIView and add the tableView and the custom UIView on top of self.view.
This is sample code from the viewController.
- (void)loadView {
UIView *aView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
//tableView
self.tableView = [[[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds] style:UITableViewStylePlain] autorelease];
//set the rowHeight once for performance reasons.
//self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.rowHeight = 75;
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.autoresizesSubviews = YES;
[aView addSubview:tableView];
//set the rowHeight once for performance reasons.
self.view = aView;
[aView release];
}
- (void)viewDidLoad {
[super viewDidLoad];
loadingView = [[LoadingView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.view addSubview:loadingView];
//fetch productsArray
[self productListRequestStart];
}
Related
I search for a lot forums but nothing found, my problem is that
I need preload some data from the web to load to the UITableView.
I saw some apps solved this problem, when show UITableView they shows "waiting circle" as modal view and after data is loaded just hide this circle.
Is there simple solution to do this?
What I need to do?
What kind of Request do I need: synchronius or asynchronius?
How to show this circle, do I need to show animatedGif or there is some internal/external control for this?
You need to make a NSThread for your "waiting circle"-(Activity Indicator).
1)Threads How do I create an NSThread that isn't the main thread.
2)Activity Indicator How to use activity indicator view.
- (void)showWaitingView {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
CGRect frame = CGRectMake(90, 190, 32, 32);
UIActivityIndicatorView* progressInd = [[UIActivityIndicatorView alloc] initWithFrame:frame];
[progressInd startAnimating];
progressInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
frame = CGRectMake(130, 193, 140, 30);
UILabel *waitingLable = [[UILabel alloc] initWithFrame:frame];
waitingLable.text = #"Processing...";
waitingLable.textColor = [UIColor whiteColor];
waitingLable.font = [UIFont systemFontOfSize:20];;
waitingLable.backgroundColor = [UIColor clearColor];
frame = [[UIScreen mainScreen] applicationFrame];
UIView *theView = [[UIView alloc] initWithFrame:frame];
theView.backgroundColor = [UIColor blackColor];
theView.alpha = 0.7;
theView.tag = 999;
[theView addSubview:progressInd];
[theView addSubview:waitingLable];
[progressInd release];
[waitingLable release];
[window addSubview:[theView autorelease]];
[window bringSubviewToFront:theView];
[pool drain];
}
- (void)removeWaitingView {
UIView *v = [window viewWithTag:999];
if(v) [v removeFromSuperview];
}
I'm trying to add a view behind my grouped UITableView. Unfortunately, whenever I scroll, the background view moves as well. This happens even when I use [self.view insertSubview:backgroundView belowSubview:_tableView], or [_tableView setBackgroundView:backgroundView]. Why is this background view scrolling? Also, why does my tableView scroll, even though I have disabled scrolling? Are these related?
In app Delegate:
History *historyController = [[History alloc] init];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:historyController];
In History.m:
- (void)viewDidLoad {
CGRect frame = self.view.frame;
frame.origin.x = 0;
frame.origin.y = 0;
_tableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStyleGrouped];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView setScrollEnabled:NO];
[_tableView setBackgroundColor:[UIColor clearColor]];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
UIView *bg = [[UIView alloc] initWithFrame:frame];
[bg setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor]];
UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"CenterFade.png"]];
iv.alpha = .750;
[bg addSubview:iv];
[iv release]; iv = nil;
[self.view addSubview:bg];
[self.view addSubview:_tableView];
[bg release]; bg = nil;
[_tableView release];
[super viewDidLoad];
}
Try
- (void)viewDidLoad {
CGRect frame = self.view.frame;
frame.origin.x = 0;
frame.origin.y = 0;
UIView *bg = [[UIView alloc] initWithFrame:frame];
[bg setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor]];
UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"CenterFade.png"]];
iv.alpha = .750;
[bg addSubview:iv];
[iv release];
iv = nil;
_tableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStyleGrouped];
_tableView.delegate = self;
_tableView.dataSource = self;
[_tableView setScrollEnabled:NO];
[_tableView setBackgroundColor:[UIColor clearColor]];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[bg addSubview:_tableView];
[_tableView release];
_tableView = nil;
[self.view addSubview:bg];
[bg release];
bg = nil;
[super viewDidLoad];
}
If your controller is an UITableViewController just change it to an UIViewController<UITableViewDelegate, UITableViewDatasource> with a tableView property (It's the same)
I don't know why this is happening, but for some reason self.view is a UITableView and not a UIView. Creating a new UIView and setting it to self.view fixed the problem. I am not using a UITableViewController, but a UIViewController. No idea where the UITableView is coming from!
set [_tableView setBackgroundColor:[UIColor clearColor]];
and then put your background view under UITableView in UIViewController view hierarchy.
UITableView has a backgroundView property.
Swift:
var backgroundView: UIView?
Objective-C
#property(nonatomic, readwrite, retain) UIView *backgroundView
This view will not be moved when you scroll the tableView
In my app when I download something from service, I show progress indicator:
- (void)setupProgressIndicator {
MBProgressHUD *progressHUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:progressHUD];
self.progressIndicator = progressHUD;
[progressHUD release];
}
[self.progressIndicator show:YES];
My view has Navigation Bar which I setup in my AppDelegate, and when indicator is shown, I still can tup on Navigation Bar Buttons...Can MBProgressHUB cover whole screen ??? Because I don't want to disable buttons on sync start and than make them enable on sync finish...I think indicator should cover whole screen. Any ideas ? Thanks...
Here is my implementation use it if you want
Put it in appDelegate and use from anywhere in the application.
#pragma mark -
#pragma mark Waiting View
- (void)showWaitingView {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
CGRect frame = CGRectMake(90, 190, 32, 32);
UIActivityIndicatorView* progressInd = [[UIActivityIndicatorView alloc] initWithFrame:frame];
[progressInd startAnimating];
progressInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
frame = CGRectMake(130, 193, 140, 30);
UILabel *waitingLable = [[UILabel alloc] initWithFrame:frame];
waitingLable.text = #"Processing...";
waitingLable.textColor = [UIColor whiteColor];
waitingLable.font = [UIFont systemFontOfSize:20];;
waitingLable.backgroundColor = [UIColor clearColor];
frame = [[UIScreen mainScreen] applicationFrame];
UIView *theView = [[UIView alloc] initWithFrame:frame];
theView.backgroundColor = [UIColor blackColor];
theView.alpha = 0.7;
theView.tag = 999;
[theView addSubview:progressInd];
[theView addSubview:waitingLable];
[progressInd release];
[waitingLable release];
[window addSubview:[theView autorelease]];
[window bringSubviewToFront:theView];
[pool drain];
}
- (void)removeWaitingView {
UIView *v = [window viewWithTag:999];
if(v) [v removeFromSuperview];
}
usual thing is to add an transparent view cover the entire screen and that will capture touch event. or you can make your HUD the size of the screen, with visible widget only in the center.
- (IBAction)showWithCustomView:(id)sender {
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.customView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"37x-Checkmark.png"]] autorelease];
HUD.customView.frame=CGRectMake(0, 0, 320, 460);//Ur answer
HUD.mode = MBProgressHUDModeCustomView;
HUD.delegate = self;
HUD.labelText = #"Completed";
[HUD show:YES];
[HUD hide:YES afterDelay:3];
}
Okay, a short breif of my app before i explain the problem.
My app has two views for it's custom TableViewCell, one frontview, and one backview(which is revealed once you swipe your finger across the cell, much like the twitter-app).
Anywho, i wanted to have some buttons on the backview. I did this in the cellForRowAtIndexPath-method
The first you'll see here is how i assign labels to the cells. The secondary thing you'll see is the button. It's working fine.
UILabel *nextArtist = [UILabel alloc];
nextArtist.text = #"Rihanna";
nextArtist.tag = 4;
[cell setNextArtist:nextArtist];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(6 ,31, 110, 20);
[button setImage:[UIImage imageNamed:#"radionorge.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(touched:) forControlEvents:UIControlEventTouchUpInside];
[cell.backView addSubview:button];
But, it's in the next method the problem occours.
-(void)touched:(id)sender {
// Here i want to get the UILabels for each cell. Such as nextArtist.
if ([sender isKindOfClass:[UIButton class]]) {
UIButton *button = (UIButton *)sender;
UIView *contentView = button.superview;
UIView *viewWithTag4 = [contentView viewWithTag:4];
if ([viewWithTag1 isKindOfClass:[UILabel class]]) {
UILabel *titleLabel = (UILabel *)viewWithTag4;
NSLog(#"Label: ",titleLabel.text);
}
}
}
So, i realised that i cannot just go to the superview of the button and find my labels there, because their in another subview. I have scanned all my views, but still cannot find the label.
I am very new at this, and the subclassing of the TableView-cell is something i implemented from someone who posted their code.
But, my assumption is that there are noe UILabels in my view, because i am not adding them as views, only drawing them, with the drawTextInRect-function.
[nextArtist drawTextInRect:CGRectMake(boundsX+200 ,46, 110, 15)];
I have tried to adding them as subviews, but with no luck. Could anyone help me?
// Some more code you may need to solve the puzzle(this is where the cell-views are made)
#implementation RadioTableCellView
- (void)drawRect:(CGRect)rect {
if (!self.hidden){
[(RadioTableCell *)[self superview] drawContentView:rect];
}
else
{
[super drawRect:rect];
}
}
#end
#implementation RadioTableCellBackView
- (void)drawRect:(CGRect)rect {
if (!self.hidden){
[(RadioTableCell *)[self superview] drawBackView:rect];
}
else
{
[super drawRect:rect];
}
}
#end
#interface RadioTableCell (Private)
- (CAAnimationGroup *)bounceAnimationWithHideDuration:(CGFloat)hideDuration initialXOrigin:(CGFloat)originalX;
#end
#implementation RadioTableCell
#synthesize contentView;
#synthesize backView;
#synthesize contentViewMoving;
#synthesize selected;
#synthesize shouldSupportSwiping;
#synthesize shouldBounce;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
[self setBackgroundColor:[UIColor clearColor]];
RadioTableCellView * aView = [[RadioTableCellView alloc] initWithFrame:CGRectZero];
[aView setClipsToBounds:YES];
[aView setOpaque:YES];
[aView setBackgroundColor:[UIColor clearColor]];
[self setContentView:aView];
[aView release];
RadioTableCellBackView * anotherView = [[RadioTableCellBackView alloc] initWithFrame:CGRectZero];
[anotherView setOpaque:YES];
[anotherView setClipsToBounds:YES];
[anotherView setHidden:YES];
[anotherView setBackgroundColor:[UIColor clearColor]];
[self setBackView:anotherView];
[anotherView release];
// Backview must be added first!
// DO NOT USE sendSubviewToBack:
[self addSubview:backView];
[self addSubview:contentView];
[self setContentViewMoving:NO];
[self setSelected:NO];
[self setShouldSupportSwiping:YES];
[self setShouldBounce:YES];
[self hideBackView];
}
return self;
}
Please help me, or at least point me in a direction or two!
//////////////////////////
Updated with some new code:
This is inside my RadioCustomCell, a UIView-subclass. It's here the UILabels are drawn
#import "RadioCustomCell.h"
#implementation RadioCustomCell
#synthesize nowTitle,nowArtist,nextTitle,nextArtist,ChannelImage;
// Setting the variables
- (void)setNowTitle:(UILabel *)aLabel {
if (aLabel != nowTitle){
[nowTitle release];
nowTitle = [aLabel retain];
[self setNeedsDisplay];
}
}
- (void)setNowArtist:(UILabel *)aLabel {
if (aLabel != nowArtist){
[nowArtist release];
nowArtist = [aLabel retain];
[self setNeedsDisplay];
}
}
- (void)setNextTitle:(UILabel *)aLabel {
if (aLabel != nextTitle){
[nextTitle release];
nextTitle = [aLabel retain];
[self setNeedsDisplay];
}
}
- (void)setNextArtist:(UILabel *)aLabel {
if (aLabel != nextArtist){
[nextArtist release];
nextArtist = [aLabel retain];
[self setNeedsDisplay];
}
}
- (void)setChannelImage:(UIImage *)aImage {
if (aImage != ChannelImage){
[ChannelImage release];
ChannelImage = [aImage retain];
[self setNeedsDisplay];
}
}
- (void)drawContentView:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
//UIColor * backgroundColour = [UIColor whiteColor];
UIColor *backgroundColour = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"CellBackground.png"]];
[backgroundColour set];
CGContextFillRect(context, rect);
CGRect contentRect = self.contentView.bounds;
CGFloat boundsX = contentRect.origin.x;
[ChannelImage drawInRect:CGRectMake(boundsX+120 ,25, 75, 35)];
nowTitle.enabled = YES;
nowTitle.textAlignment = UITextAlignmentCenter;
nowTitle.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size: 14.0];
nowTitle.textColor = [UIColor blackColor];
nowTitle.backgroundColor = [UIColor clearColor];
//[nowTitle drawTextInRect:CGRectMake(boundsX+6 ,31, 110, 20)];
// Trying to add a subview instead of drawing the text
nowTitle.frame = CGRectMake(boundsX+6 ,31, 110, 20);
[self addSubview:nowTitle];
// I have also tried adding it to super, no effect.
nowArtist.enabled = YES;
nowArtist.textAlignment = UITextAlignmentCenter;
nowArtist.font = [UIFont fontWithName:#"HelveticaNeue" size: 10.0];
nowArtist.textColor = [UIColor blackColor];
nowArtist.backgroundColor = [UIColor clearColor];
[nowArtist drawTextInRect:CGRectMake(boundsX+6 ,46, 110, 15)];
nextTitle.enabled = NO;
nextTitle.textAlignment = UITextAlignmentCenter;
nextTitle.font = [UIFont fontWithName:#"HelveticaNeue-Bold" size: 12.0];
[nextTitle drawTextInRect:CGRectMake(boundsX+200 ,31, 110, 20)];
nextArtist.enabled = NO;
nextArtist.textAlignment = UITextAlignmentCenter;
nextArtist.font = [UIFont fontWithName:#"HelveticaNeue" size: 9.0];
[nextArtist drawTextInRect:CGRectMake(boundsX+200 ,46, 110, 15)];
}
You just forgot to init your UILabel in your very first line of code. :)
At the first look, I can be sure that if you draw the text (and the text is not the label), then there is no UILabel at all in your cell. You can ignore that way.
So, if you don't have the UILabel, how you can get the text. Because your contentView is indeed a RadioTableCellView, then it is not hard. In your class, just public a property called nextArtist. When your button is tapped, look up for the contentView (by calling some superview), cast it to RadioTableCellView then get the nextArtist out
Without writing a bunch of code, here's my best guess.
You're going to need to assign tags to aView and anotherView in your initWithStyle: method. I'm going to assume you have a couple constants: BACK_VIEW_TAG and FRONT_VIEW_TAG.
In your touched: method, walk up the view hierarchy until you find your UITableViewCell.
UIView *currentView = button.superView;
while (![currentView isKindOfClass:UITableViewCell] && currentView != nil) {
currentView = currentView.parent;
}
Get the front view and back view (or which ever you want) from the table cell's contentView using the tags.
if (currentView != nil) {
UITableViewCell *cellView = (UITableViewCell *)currentView)
UIView *cellContentView = cellView.contentView;
UIView *backView = [cellContentView viewWithTag:BACK_VIEW_TAG];
UIView *frontView = [cellContentView viewWithTag:FRONT_VIEW_TAG];
// Get other views from frontView and backView using viewWithTag:.
}
Note that you should be adding views to your UITableViewCell subclass's contentView, not to the UITableViewCell directly. See Programmatically Adding Subviews to a Cell’s Content View for details.
I want to add a custom UIImageView to UISearchDisplayController's table view background and set table view's background color to clearColor. Tried a few different approach but couldn't find the right solution. Any idea how to approach this?
Note: I don't want to add to searchDisplayController's searchResultsTableView's view hierarchy, but rather overlay another sibling view below it)
You can set the background image in a similar way you would for your main table, only set it in the searchDisplayControllerDidBeginSearch delegate method. For instance:-
- (void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
[controller.searchResultsTableView setDelegate:self];
UIImageView *anImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"gradientBackground.png"]];
controller.searchResultsTableView.backgroundView = anImage;
[anImage release];
controller.searchResultsTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
controller.searchResultsTableView.backgroundColor = [UIColor clearColor]; }
You can also do this wherever you instantiate your UISearchDisplayController. In my app I was doing this in my UITableView viewDidLoad method and was matching the styles between the two tables:
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.separatorColor = [UIColor blackColor];
self.tableView.backgroundColor = [UIColor grayColor];
self.tableView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
searchController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
searchController.delegate = self;
searchController.searchResultsDataSource = self;
searchController.searchResultsDelegate = self;
searchController.searchResultsTableView.separatorColor = self.tableView.separatorColor;
searchController.searchResultsTableView.backgroundColor = self.tableView.backgroundColor;
searchController.searchResultsTableView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
}