cannot remove UISearchBar - iphone

I create SearchBarView, a subclass of UIView, and added UISearchBar as a subview to it. After calling removeFromSuperview on SearchBarView (from searchBarSearchButtonClicked) the UISearchBar does not disappear. I tried to call removeFromSuperview on SearchBarView from where I created SearchBarView but it did not help. Any ideas why?
#import <UIKit/UIKit.h>
#interface SearchBarView : UIView <UISearchBarDelegate> {
UISearchBar *querySearchBar;
}
#end
#import "SearchBarView.h"
#implementation SearchBarView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
querySearchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0,0,frame.size.width,44)];
querySearchBar.delegate = self;
[self addSubview:querySearchBar];
}
return self;
}
#pragma mark -
#pragma mark UISearchBarDelegate methods
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self removeFromSuperview];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
searchBar.text = #"";
[searchBar resignFirstResponder];
[searchBar setShowsCancelButton:NO animated:YES];
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
[searchBar setShowsCancelButton:NO animated:YES];
return YES;
}
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
[searchBar setShowsCancelButton:YES animated:YES];
return YES;
}
#end
SearchBarView is created as follows:
SearchBarView *searchBarView = [[SearchBarView alloc] initWithFrame:CGRectMake(0, 0, 480, 300)];
UIView *rootView = [[[[UIApplication sharedApplication] delegate] window] rootViewController].view;
[rootView addSubview:searchBarView];

Your problem is
[self addSubview:querySearchBar];
If you add searchcontroller to subview, then when you do these it does not work.
[searchController.searchBar removeFromSuperview()]
self.definesPresentationContext = true
searchController.active = false
I suggest your to do
presentViewController(searchController, animated: true, completion: nil)
And try to dismiss searchController
[searchController.searchBar removeFromSuperview()]

try
[searchbar removefromsuperview];

Related

Can't dismiss modal view when tap a button

In "FirstViewController" I declare a button which present the modal view "InfoViewController".
In "InfoViewController", I declare a toolbar with a "modalViewButton" UIButton which dismiss the modal view. But the "OK" UIButton doesn't work. I don't know why.
Here's FirstViewController.h
#import <UIKit/UIKit.h>
#import "InfoViewController.h"
#interface FirstViewController : UIViewController
{
InfoViewController *infoViewController;
}
#property (nonatomic, retain) InfoViewController *infoViewController;
#end
Here's FirstViewController.m
#import "FirstViewController.h"
#implementation FirstViewController
#synthesize infoViewController;
- (IBAction)modalViewAction:(id)sender
{
if (self.infoViewController == nil)
self.infoViewController = [[[InfoViewController alloc] initWithNibName:
NSStringFromClass([InfoViewController class]) bundle:nil] autorelease];
[self presentModalViewController:self.infoViewController animated:YES];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[infoViewController release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton* modalViewButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[modalViewButton addTarget:self
action:#selector(modalViewAction:)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *modalBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:modalViewButton];
self.navigationItem.leftBarButtonItem = modalBarButtonItem;
[modalBarButtonItem release];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Here's InfoViewController.h
#import <UIKit/UIKit.h>
#interface InfoViewController : UIViewController
{
}
-(IBAction)infoDismissAction:(id)sender;
#end
Here's the InfoViewController.m
#import "InfoViewController.h"
#implementation InfoViewController
- (IBAction)infoDismissAction:(id)sender
{
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
UILabel *infoLabel = [[UILabel alloc] init];
infoLabel.frame = CGRectMake(50, 100, 100, 40);
infoLabel.textAlignment = UITextAlignmentCenter;
infoLabel.text = #"About";
[self.view addSubview:infoLabel];
UIToolbar *toolBar;
toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
toolBar.frame = CGRectMake(0, 0, 320, 50);
toolBar.barStyle = UIBarStyleDefault;
[toolBar sizeToFit];
UIBarButtonItem *flexibleSpace = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil] autorelease];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:#"OK"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(infoDismissAction:)];
UIBarButtonItem* infoTitle = [[UIBarButtonItem alloc] initWithTitle:#"About"
style:UIBarButtonItemStylePlain
target:self action:nil];
NSArray *barButtons = [[NSArray alloc] initWithObjects:flexibleSpace,flexibleSpace,infoTitle,flexibleSpace,doneButton,nil];
[toolBar setItems:barButtons];
[self.view addSubview:toolBar];
[toolBar release];
[infoTitle release];
[doneButton release];
[barButtons release];
[infoLabel release];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
I would solve this issue with a delegate method.
First make a protocol in your modalViewController
#protocol ModalViewDelegate <NSObject>
- (void)didDismissModalView;
#end
And set a delegate property in the same modalVC:
id<ModalViewDelegate> dismissDelegate;
Then make a buttonActionMethod that calls the delegate in the modalVC:
- (void)methodCalledByButton:(id)sender
{
// Call the delegate to dismiss the modal view
[self.dismissDelegate didDismissModalView];
}
Now your modalVC is done you have to prepare the mainVC calling the modalVC:
You have to make your MainViewController comform to the delegate:
#interface MainViewController : UIViewController <ModalViewDelegate>
At the place you alloc your ModalViewController you have to set the delegate property you made in your modalViewController:
self.myModalViewController.dismissDelegate = self;
Now the MainViewController listens to the delegate and the only thing you need to do is implement the delegateMethod.
-(void)didDismissModalView
{
[self dismissModalViewControllerAnimated:YES];
}
Now your ModalVC will dismiss on a buttonpress (at least when you call the method properly)
Hope this all makes sense.
Good luck.
You can only dismiss currently displayed modal view, so in your method infoDismissAction: you should do one of following
1) [self dismissModalViewControllerAnimated:YES];
2) Send to parent view controller message that current modal view should be dismissed and send reference to that view.
Second approach is better as it is more safe.
In your -infoDismissAction try to call [self dismissModalViewControllerAnimated:YES];
Here the best sample code for the model view for iphone and ipad also.
The popups have a number of configurable items. They can be animated to either slide or popup onto the display. Once visible, they can be dismissed either by tapping the screen or after a programmed delay. The background and text colors can also be adjusted however you like.
Download the sample code from here.
The current answers are deprecated. Here is the updated code:
[self dismissViewControllerAnimated:NO completion:nil];

Can not get UITableView to Display NSArray

Sounds like a question that has been answered... maybe but i have checked all of the possible solutions i believe and nothing will work for me.
My .h file looks like this
#import <UIKit/UIKit.h>
#interface epsMenuPage : UIViewController<UITableViewDelegate,UITableViewDataSource>{
NSArray *listData;
...
UITableView *menuList;
...
}
#property (nonatomic,retain) NSArray *listData;
...
#property (nonatomic, retain) IBOutlet UITableView *menuList;
...
#end
My .m file looks like this
#implementation epsMenuPage
#synthesize listData;
...
#synthesize menuList;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
//Arrays credit,debit and both
creditListData = [[NSArray alloc]initWithObjects:#"Return",#"Force Sale",#"Authorize Only",#"Total Sales",#"Items Sold",#"Reciept's", nil];
debitListData = [[NSArray alloc]initWithObjects:#"Return",#"Force Sale",#"Authorize Only",#"Total Sales",#"Items Sold",#"Reciept's", nil];
bothListData = [[NSArray alloc]initWithObjects:#"Batch History",#"Settle Batch", nil];
self.listData = creditListData;
[menuList reloadData];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.view.backgroundColor =[UIColor colorWithRed:255/255.0 green:95/255.0 blue:95/255.0 alpha:1.0];
[colorChange setBackgroundColor:[UIColor colorWithRed:255/255.0 green:95/255.0 blue:95/255.0 alpha:1.0]];
[self.view addSubview:creditTabButton];
[self.view addSubview:debitTabButton];
[self.view addSubview:bothTabButton];
[self.view addSubview:creditButtonText];
[self.view addSubview:debitButtonText];
[self.view addSubview:bothBottonText];
[self.view addSubview:colorChange];
}
- (void)viewDidUnload
{
[self setTitleBAckButton:nil];
[self setTitleSettingsButton:nil];
[self setCreditTabButton:nil];
[self setDebitTabButton:nil];
[self setBothTabButton:nil];
[self setMenuList:nil];
[self setColorChange:nil];
[self setCreditButtonText:nil];
[self setDebitButtonText:nil];
[self setBothBottonText:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.listData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = #"tableID";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [self.listData objectAtIndex:row];
return cell;
}
- (void)dealloc {
[titleBAckButton release];
[titleSettingsButton release];
[creditTabButton release];
[debitTabButton release];
[bothTabButton release];
[menuList release];
[colorChange release];
[creditButtonText release];
[debitButtonText release];
[bothBottonText release];
[listData release];
[super dealloc];
}
- (IBAction)titleBackClick:(id)sender {
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
- (IBAction)titleSettingsClick:(id)sender {
}
- (IBAction)creditTabClick:(id)sender {
self.listData = creditListData;
[menuList reloadData];
[colorChange setBackgroundColor:[UIColor colorWithRed:255/255.0 green:95/255.0 blue:95/255.0 alpha:1.0]];
[self.view addSubview:creditTabButton];
[self.view addSubview:creditButtonText];
[self.view addSubview:colorChange];
self.view.backgroundColor = [UIColor colorWithRed:255/255.0 green:95/255.0 blue:95/255.0 alpha:1.0];
}
- (IBAction)debitTabClick:(id)sender {
self.listData = debitListData;
[menuList reloadData];
[colorChange setBackgroundColor:[UIColor colorWithRed:244/255.0 green:133/255.0 blue:33/255.0 alpha:1.0]];
[self.view addSubview:debitTabButton];
[self.view addSubview:debitButtonText];
[self.view addSubview:colorChange];
self.view.backgroundColor = [UIColor colorWithRed:244/255.0 green:133/255.0 blue:33/255.0 alpha:1.0];
}
- (IBAction)bothTabClick:(id)sender {
self.listData = bothListData;
[menuList reloadData];
[colorChange setBackgroundColor:[UIColor colorWithRed:72/255.0 green:72/255.0 blue:255/255.0 alpha:1.0]];
[self.view addSubview:bothTabButton];
[self.view addSubview:bothBottonText];
[self.view addSubview:colorChange];
self.view.backgroundColor = [UIColor colorWithRed:72/255.0 green:72/255.0 blue:255/255.0 alpha:1.0];
}
#end
I really for the life of me can not figure out why it wont display to my TableView, i have tried so many different tutorials.
any help is greatly appreciated.
You're never adding the menuList table view to your view. Add it and see if that does the trick:
// In -viewDidLoad
[self.view addSubview:menuList];
EDIT 1: Did you declare properties in your .h? These aren't visible, so it appears as if you're not creating or adding your table view to the view controller's view. However, if you are using IBOutlets, then this probably isn't the issue.
EDIT 2: From the comments below, your dataSource is nil, which is exactly why nothing is being displayed. Make sure your table view in Interface Builder has its dataSource outlet pointing to your view controller. To be double sure, delete the table view from Interface Builder and add it back again. Make sure your connections are exactly right. Also try cleaning the project and rebuilding, as well as restarting Xcode.
It looks like you are missing the required datasource method:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; {
return 1;
}
Also, it looks like you are not actually initializing your UIButton's, or anything you are adding as a subview. Are you using a nib?

UITableView scrolls too far when editing embedded UITextView

I've successfully embedded a UITextView inside a UITableViewCell, and most of the table is working fine. However, when I enable editing on the UITextView and start editing, the table shifts up too far, obscuring the cursor. Is there a way to control how far the tableview scrolls? Manually scrolling the view to the cell works, but the view still scrolls up before scrolling back down and into view.
Here is an example of what I mean:
editing a UITextField - the field is neatly placed directly above the keyboard.
http://imageshack.us/photo/my-images/13/textfield.png/
editing a UITextView - the field is placed significantly above the keyboard removing the toolbar from the keyboard doesn't affect anything)
http://imageshack.us/photo/my-images/809/textview.png/
Here's all the code that is relevant to the UITextView in the UITableViewController object:
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(keyboardWillShow:)
name: UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(keyboardWillHide:)
name: UIKeyboardWillHideNotification object:nil];
}
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
viewTargetedForEditing = (UIView *)textView;
return YES;
}
- (void)textViewDidBeginEditing:(UITextView *)textView
{
[self.navigationController setNavigationBarHidden:YES animated:YES];
// shrink the textView to fit on-screen
originalTextViewFrame = textView.frame;
CGRect keyboardRect = [[keyboardUserinfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat keyboardHeight = keyboardRect.size.height;
CGRect newViewFrame = textView.frame;
CGFloat spaceAboveKeyboard = self.containerView.frame.size.height - keyboardHeight;
newViewFrame.size.height = (spaceAboveKeyboard < textView.frame.size.height) ? spaceAboveKeyboard : textView.frame.size.height;
/* animate the calculations */
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[[keyboardUserinfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
textView.frame = newViewFrame;
[UIView commitAnimations];
// recalculate the keyboard height, in case we aren't in portrait mode
CGFloat toolbarHeight;
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
toolbarHeight = 44.0;
} else {
toolbarHeight = 32.0;
}
CGRect frame = textView.inputAccessoryView.frame;
frame.size.height = toolbarHeight;
}
- (void)endTextViewEditing
{
[viewTargetedForEditing resignFirstResponder];
}
- (void)textViewDidEndEditing:(UITextView *)textView
{
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
#pragma mark - Keyboard Notifications
- (void)keyboardWillShow:(NSNotification *)notification
{
[keyboardUserinfo release];
keyboardUserinfo = [[notification userInfo] retain];
[self viewDidBeginEditing:viewTargetedForEditing];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
[keyboardUserinfo release];
keyboardUserinfo = [[notification userInfo] retain];
[self viewDidEndEditing:viewTargetedForEditing];
}
- (void)viewDidBeginEditing:(id)aView
{
// called 2nd
UITableViewCell *cell = (UITableViewCell *)[aView superview];
[self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
- (void)viewDidEndEditing:(id)aView
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[viewTargetedForEditing superview]];
gallupAppDelegate *appDelegate = (gallupAppDelegate *)[[UIApplication sharedApplication] delegate];
switch (indexPath.section) {
case SectionDescription:
if (![[(UITextField *)aView text] isEqualToString:self.plan.Description]) {
self.plan.Description = [(UITextField *)aView text];
[appDelegate saveManagedContext];
}
break;
case SectionNotes:
if (![[(UITextView *)aView text] isEqualToString:self.plan.Notes]) {
self.plan.Notes = [(UITextView *)aView text];
[appDelegate saveManagedContext];
}
break;
case SectionLocation:
if (![[(UITextField *)aView text] isEqualToString:self.plan.Location]) {
self.plan.Location = [(UITextField *)aView text];
[appDelegate saveManagedContext];
}
break;
}
}
The TextViewCell is a subclass of UITableViewCell, and it is the cell that is giving me the problem with scrolling.Here's the implementation:
#implementation TextViewCell
#synthesize contents=_contents;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
_contents = [[UITextView alloc] initWithFrame:CGRectZero];
[self addSubview:_contents];
self.contents.font = [UIFont systemFontOfSize:17];
self.contents.dataDetectorTypes = UIDataDetectorTypeAll;
CGRect frame = CGRectMake(0, 0, self.window.frame.size.width, 44.0);
UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *done = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(endTextViewEditing)];
UIToolbar *textViewToolbar = [[UIToolbar alloc] initWithFrame:frame];
textViewToolbar.barStyle = UIBarStyleBlackOpaque;
[textViewToolbar setItems:[NSArray arrayWithObjects:spacer, done, nil]];
self.contents.inputAccessoryView = textViewToolbar;
}
return self;
}
- (void)endTextViewEditing
{
[self.contents resignFirstResponder];
}
#define LEFT_MARGIN 15
#define TOP_MARGIN 5
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat width = self.frame.size.width - (LEFT_MARGIN *2);
CGFloat height = self.frame.size.height - (TOP_MARGIN *2);
self.contents.frame = CGRectMake(LEFT_MARGIN, TOP_MARGIN, width, height);
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
//[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)dealloc
{
[super dealloc];
}
#end
As it turns out, subclassing the UITableView and implementing the following fixed the problem:
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
{
[super setContentOffset:contentOffset animated:animated];
return;
static int i = 0;
if (0 == i) {
i++;
} else {
i = 0;
[super setContentOffset:contentOffset animated:animated];
}
return;
}
Apparently the -setContentOffset:animated: message was sent 2x, and if the first one is allowed to run the second time round doesn't do it's job properly.
Does anyone have any insite as to why this would fix the problem?

UITextView setEditing:YES makes the control of the TextView scroll?

I have a UITableViewCell that has an integrated UITextView. The goal is to make a cell that auto-expands while editing. The issue right now is that when the UITableViewController sends setEditing:YES, the UITextView scrolls and clips some of the text at the top.
I'm sure there is a better way to do this but I just don't know how...
#import "PLTextViewCell.h"
#implementation PLTextViewCell
#synthesize delegate=_delegate;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {
_textView = [[UITextView alloc] initWithFrame:CGRectMake(90, 0, 200, 80)];
[_textView setEditable:NO];
[_textView setFont:[UIFont systemFontOfSize:15.0]];
[_textView setDelegate:self];
[_textView setScrollEnabled:NO];
[[self contentView] addSubview:_textView];
}
return self;
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[_textView setEditable:editing];
[_textView scrollRangeToVisible:NSMakeRange(0, 1)];
[self textViewDidChange:_textView];
}
- (void)dealloc {
[_textView dealloc];
[super dealloc];
}
- (void)setTextValue:(NSString *)value {
[_textView setText:value];
[self textViewDidChange:_textView];
}
- (NSString *)textValue {
return [_textView text];
}
- (CGFloat)cellHeight {
CGSize mySize = [_textView contentSize];
NSLog(#"cell height: %f", mySize.height);
return mySize.height;
}
#pragma mark -
#pragma mark Text view delegate
- (void)textViewDidChange:(UITextView *)textView {
CGSize mySize = [_textView contentSize];
if (mySize.height > self.bounds.size.height) {
[textView scrollRectToVisible:CGRectMake(0,textView.contentSize.height-1,1,1) animated:NO];
if ([self delegate] != nil) {
[[self delegate] tableViewCellDidChangeHeight:self];
}
[textView setFrame:CGRectMake(90, 0, mySize.width, mySize.height)];
[self setNeedsLayout];
}
}
#end
Then the Table view implements a delegation method:
- (void)tableViewCellDidChangeHeight:(PLTextViewCell *)cell {
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
Any ideas? Am I doing this all wrong?
Turns out that it was the UIEdgeInset combined with my textview not being tall enough. My mistake!

Present a default view instead of tableview if datasource is empty

The iOS app I'm currently working on is tabbar-based, and one of the tab is a UITableViewController.
The thing is, when I open this tab with an empty datasource (for whatever reason), I'd like to bring another view, with some kind of message/image, instead of the blank view I get with the tableviewcontroller.
I tried something like that :
- (void)viewWillAppear:(BOOL)animated {
if ([myData count] == 0) {
if (!emptyView) {
emptyView = [[UIView alloc] initWithFrame:self.view.frame];
UILabel *emptyMsg = [[UILabel alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height / 2, self.view.frame.size.width, 20)];
emptyMsg.text = #"This is Empty !";
emptyMsg.textAlignment = UITextAlignmentCenter;
[emptyView addSubview:emptyMsg];
}
[self.view insertSubview:emptyView atIndex:0];
}
else {
if (emptyView != nil) { [emptyView removeFromSuperview]; emptyView = nil; }
[self.tableView reloadData];
[super viewWillAppear:animated];
}
}
With emptyView defined as an iVar in the view controller.
But It doesn't work as expected, and I can't find the reason :/
Could any of you give it a look and give me the proper way to do this kind of behavior ?
Thanks,
I solved this problem by adding a UIView in the tableview header with a frame size equal to tableview size and disallowing user interaction on the tableview:
UIView *emptyView = [[UIView alloc] initWithFrame:self.tableView.frame];
/* Customize your view here or load it from a NIB */
self.tableView.tableHeaderView = emptyView;
self.tableView.userInteractionEnabled = NO;
When you have data you just remove the header and reenable user interaction:
self.tableView.tableHeaderView = nil;
self.tableView.userInteractionEnabled = YES;
UITableViewController doesn't allow you to add subviews to it's view (the tableView).
You should make a UIViewController and add the UITableView yourself with your optional emptyView.
Don't forget to set the dataSource and the delegate!
Update : I've made a subclass of UIViewController to avoid mimics UITableViewController every time.
.h
//
// GCTableViewController.h
// GCLibrary
//
// Created by Guillaume Campagna on 10-06-17.
// Copyright 2010 LittleKiwi. All rights reserved.
//
#import <UIKit/UIKit.h>
//Subclass of UIViewController that mimicks the UITableViewController except that the tableView is a subview of self.view and allow change of the frame of the tableView
#interface GCTableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, readonly) UITableView *tableView;
- (id) initWithStyle:(UITableViewStyle)style;
//Subclass if you want to change the type of tableView. The tableView will be automatically placed later
- (UITableView*) tableViewWithStyle:(UITableViewStyle) style;
#end
.m
//
// GCTableViewController.m
// GCLibrary
//
// Created by Guillaume Campagna on 10-06-17.
// Copyright 2010 LittleKiwi. All rights reserved.
//
#import "GCTableViewController.h"
#implementation GCTableViewController
#synthesize tableView;
- (id) initWithStyle:(UITableViewStyle) style {
if (self = [super initWithNibName:nil bundle:nil]) {
tableView = [[self tableViewWithStyle:style] retain];
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tableView];
self.tableView.frame = self.view.bounds;
self.tableView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
}
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}
#pragma mark TableView methods
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
return 0;
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
return nil;
}
#pragma mark Getter
- (UITableView *) tableViewWithStyle:(UITableViewStyle)style {
return [[[UITableView alloc] initWithFrame:CGRectZero style:style] autorelease];
}
- (void)dealloc {
[tableView release];
tableView = nil;
[super dealloc];
}
#end
You could perhaps try setting the number of rows to zero. Then inserting the no results view as the header view.