iOS TableViewController in PopOver disappears after touching tableview - ios

I am developing universal iOS app and try to achieve popover.
I have tried WYPopoverController and FPPopover but those 2 does the same issue.
I have simple UITableViewController having 10 cells putting a static text on each cell (just for a test).
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
UILabel *label = (UILabel *) [cell viewWithTag:1];
[label setText:#"test"];
return cell;
}
and try to show this in popover.
Sample code to apply FPPopover is
- (IBAction)test:(id)sender {
PopOverTableViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"PopOverTableViewController"];
FPPopoverController *popOver = [[FPPopoverController alloc] initWithViewController:vc];
[popOver presentPopoverFromView:sender];
}
This shows text in 10 cells at a button tap but once I scroll inside of tableview,
the texts disappear and non of tableview data source methods are called afterwards.
It happened for both WYPopoverController and FPPopover so I am assuming there is something wrong in my side.
However, I could not figure out where I went wrong.
I appreciate your help on this.

Thank you guys for answering my question.
I solved myself. It was due to having FPPopoverController as in local variable. I needed to put as instance variable with strong property, otherwise the controller is deallocated by ARC. That made a popover frame is still visible but table view content inside of popover is dismissed.

I am not sure what FFPopoverController does but in case of a normal popover controller you can use popover delegate method "popoverControllerShouldDismissPopover" to restrict the disappearance of a popover like following:
-(BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController {
return NO;
}
Surely, you need to declare UIPopoverControllerDelegate to the .h file of your view controller and set the "delegate" property of the popover controller to "self", for the above method to work.

Related

didSelectRowAtIndexPath not called on Touch

My didSelectRowAtIndexPath method not called. I reload table and its reloaded and also called all methods of talbeView
Here is my all methods of tableview :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *s = (NSString *) [app.Glb.arrayRoomList objectAtIndex:indexPath.row];
NSString *cellIdentifire = #"CellRoomList";
CellRoomList *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifire];
if(cell == nil)
{
cell = (CellRoomList*)[[[NSBundle mainBundle] loadNibNamed:#"CellRoomList" owner:self options:nil] objectAtIndex:0];
}
cell.lblRoomName.text = s;
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [app.Glb.arrayRoomList count];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *userName = (NSString *) [app.Glb.arrayRoomList objectAtIndex:indexPath.row];
NSLog(#"userName :---- %#",userName);
ViewController *chatController = [[ViewController alloc] init];
chatController.chatWithUser = userName;
[self.navigationController pushViewController:chatController animated:YES];
}
I read some questions in stack but can't get answers.
and if i long touch to cell than it cell's color change but not called didSelectRowAtIndexPath
Why its not called ?
Here is Snap :
There might be other views in cell that could intercepting the touch events. Make sure to set NO to the property userInteractionEnabled for views.
I had faced this general issue so many times.
Please take care of following things
Make sure your cell dont have any type of touch/tap gestures to its contents
Make sure your view dont have any touch/tap gestures applied
Make sure you dont have any View or Table view categories(extension) that has any touch/tap gestures applied [This is more critical as we don`t expect this usually]
Check if you have any third party who works for touch/tap gestures
The most common reasons are gestures on view that prevent the table to get touches on cell.
As you told you are getting user name, it means your method is calling but not redirecting to another screen, as you have initiate view controller in wrong manner so change it by below,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *userName = (NSString *) [app.Glb.arrayRoomList objectAtIndex:indexPath.row];
NSLog(#"userName :---- %#",userName);
ViewController *chatController = [[ViewController alloc] initWithNibName:#"ViewControllerId" bundle:nil];
chatController.chatWithUser = userName;
[self.navigationController pushViewController:chatController animated:YES];
}
Check if selection is set to single selection!

Changing custom tableview cell button background image using NSNotification from non-tableview host class

1) I have a simple table view hosted by view controller and cell hosted by custom UITableViewCell class. A button on my cell drops down a menu (a simple table view controller loading from the non-host 'out of the picture' class using FPPopoverMenu).
2) The problem is I want to update my button background image on dropdown menu row selection which involves my 'out of the picture dropdown menu tableview class' and my 'custom table view cell class' totally deserting the host of my custom UITableViewCell.
3) I tried using NSNotification like, I successfully did for a simple scenario involving only host-class and dropdown menu class but now its the custom tableview cell (which is a repeating entity) and dropdown class I want to communicate.. Please help. I set up NSNotification but background image stays the same, means notification doesn't reach/doesn't reach in time.
4) Apparently I need 10 reputation to post image (:-[) so here's the link:
As shown by the image, I have fired notification on dropdown's didSelectRow, when Hide is pressed, background should change otherwise, if show is pressed it should be green as shown..as i did before but this doesn't do anything for me. Any help will be greatly appreciated. thank you in advance!
To achieve this you can use blocks.
You need to add
#property (nonatomic, copy) void (^didSelectAction)(NSIndexPath *indexPath);
to view controller which is shown in popover.
than in tableView: didSelectRowAtIndexPath: call this block
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.didSelectAction)
self.didSelectAction(indexPath);
}
So when you create a popover you should provide additional handler.
Something like this
Add new action to your button
- (UITableViewCell *) tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
[[cell button] addTarget:self action:#selector(showPopoverFromButton:) forControlEvents:UIControlEventTouchUpInside];
}
- (void) showPopoverFromButton:(UIButton *)sender {
//Your table view which is shown in popover
UITableViewController *controller = [[UITableViewController alloc] init];
[controller setDidSelectAction:^{
[sender setBackgroundColor:[UIColor redColor]];
}];
FPPopoverMenu *popover = [[FPPopoverController alloc] initWithViewController:controller];
[popover show];
}

UITableViewCells get emptied on scroll (objc)

UITableViewCells get emptied on scroll (Objective-C)
I am having a problem with UITableViewCells getting emptied as soon I a start to scroll within the table view.
I already had a look at Cells become empty after scrolling. (Xcode) - however the problem still persists.
1) I have a popover view controller, which presents a way to log into some administration. Upon successful login (which hasn’t been implemented yet, the LOGIN button simply takes one straight to a test tableView - which should be fed from some external database later on).
2) Upon successful login, the login view inside the popover gets removed and a custom UITableViewController comes into play with its own XIB.
3) This UITableViewController uses a custom UITableViewCell - since prototype cells are not possible within this configuration.
It all works to the point where I scroll the table - and all the cells get emptied for some reason.
Here is the code run down (I leave out the obvious, eg properties and table section, etc setups):
1) customPopUpViewController(XIB ,.h, .m):
- (IBAction)loginButtonPressed:(UIButton *)sender {
UITableViewController *libraryTableViewController = [[LibraryAdminTableViewController alloc]initWithNibName:#"LibraryAdminTableViewController" bundle:nil];
libraryTableViewController.view.frame = CGRectMake(0, 179, libraryTableViewController.view.frame.size.width, libraryTableViewController.view.frame.size.height);
[self.view addSubview:libraryTableViewController.view];
}
2) LibraryAdminTableViewController (XIB ,.h, .m):
- (void)viewDidLoad {
[super viewDidLoad];
self.LibraryAdminTable.delegate = self;
self.LibraryAdminTable.dataSource = self;
self.tblContentList = [[NSMutableArray alloc]init];
self.tblContentList = [NSMutableArray arrayWithObjects:#"Sync Pack 1",#"Sync Pack 2",#"Sync Pack 3", nil];
[self.LibraryAdminTable registerNib:[UINib nibWithNibName:#"LibraryAdminTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:#"LibraryAdminCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
LibraryAdminTableViewCell *cell = [self.LibraryAdminTable dequeueReusableCellWithIdentifier:#"LibraryAdminCell" forIndexPath:indexPath];
NSString* trackList = [self.tblContentList objectAtIndex:indexPath.row];
cell.cellLabel.text = trackList;
return cell;
}
3) LibraryAdminTableViewCell (XIB ,.h, .m) - I gave the Identifier in the Attributes Inspector “LibraryAdminCell”:
#property (strong, nonatomic) IBOutlet UILabel *cellLabel;
What am I missing?
It is solved. According to this thread I had to get a strong reference to the custom UITableViewController via a property in the popup controller since the ViewController (being the DataSource for the tableView) would not be retained in memory.
This is happening because you are not creating a new cell, when tableview will try to dequeue a cell, and it does not get the cell, then it should create the cell to use but you are not creating any cell, so it is returning nil.Try the code below
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
LibraryAdminTableViewCell *cell = (LibraryAdminTableViewCell*)[self.LibraryAdminTable dequeueReusableCellWithIdentifier:#"LibraryAdminCell"
forIndexPath:indexPath];
if (cell == nil)
{
cell = [[LibraryAdminTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"LibraryAdminCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
NSString* trackList = [self.tblContentList objectAtIndex:indexPath.row];
cell.cellLabel.text = trackList;
return cell;
}

Custom UITableViewCell in storyboard won't load

I'm facing a strange problem. I have an iOS 7.1 storyboard app with a UITableViewController using Xcode 5. I created a subclass of UITableViewCell and set it as the class for the cell from the IB and also added a cell identifier. The style is set to Custom as well. I haven't made any modifications to this subclass yet though. It has only the template code you get when you create a new class.
In the table view controller I have this code. Just setting the data source and the delegate methods.
#import "TableViewController.h"
#import "TextFieldTableViewCell.h"
#interface TableViewController ()
#end
#implementation TableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
TextFieldTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.textLabel.text = #"hello world";
return cell;
}
In the cellForRowAtIndexPath, I simply set a value to the textLabel property of the cell. Even that doesn't get shown up. I double checked the identifier, style and everything bit they are all set.
I have no idea why this isn't working. I also checked out a few online tutorials on this subject matter like this one but I have everything as they've described.
Can anyone please tell me if I'm missing anything?
I've uploaded a test project to my Dropbox here if you want to take a quick look at it.
Found it! You've overridden the layoutSubviews of TextFieldTableViewCell class, and wrote nothing inside of it.
Just remove the layoutSubviews (for now) and it will work.
Update: A better solution;
- (void) layoutSubviews
{
[super layoutSubviews];
}

Fails to call delegate/datasource methods in UITableView implementation

I have created .h and .m files for UITableView called mainTableViewgm.h and mainTableViewgm.m resp. and I am calling -initWithFrame: method from my main view controller to this mainTableViewgm.m implementation file
[[mainTableViewgm alloc]initWithFrame:tableViewOne.frame]
Note that this tableview is in my main view controller. But I have created separate files for the tableView and have also set the custom class to mainTableViewgm in storyboard.
the -initWithFrame: methods appears as follows
- (id)initWithFrame:(CGRect)frame
{
//NSLog(#"kource data");
self = [super initWithFrame:frame];
if (self)
{
[self setDelegate:self];
[self setDataSource:self];
[self tableView:self cellForRowAtIndexPath:0];
[self tableView:self numberOfRowsInSection:1];
// Initialization code
}
return self;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"kource data");
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"kource data2");
UITableViewCell*cellOne =[[UITableViewCell alloc]init];
cellOne.detailTextLabel.text=#"text did appear";
return cellOne;
}
the -initWithFrame: is being called fine along with the 'if (self)' block in this method. But the problem is numberOfRowsInSection: and cellForRowAtIndexPath: are not being automatically called here . kource data/kource data2 never appear in log. What do I do to load the table? Are the delegate/datasource being set incorrectly?
I must mention that I have also set the UITableViewDelegate and UITableviewDataSource protocols:
#interface mainTableViewgm : UITableView <UITableViewDelegate,UITableViewDataSource>
#end
Help will be much appreciated. Thank you.
Your tableview is not loaded when the controller is initializing, so you cannot do that in the init methods. You have to move your code to the viewDidLoad method.
Also you are not setting the delegate and datasource on the tableview object (probably a type, you are setting them on the view controller). It should look like this:
- (void)viewDidLoad:(BOOL)animated {
[super viewDidLoad:animated];
[self.tableView setDelegate:self];
[self.tableView setDataSource:self]; // <- This will trigger the tableview to (re)load it's data
}
Next thing is to implement the UITableViewDataSource methods correctly. UITableViewCell *cellOne =[[UITableViewCell alloc] init]; is not returning a valid cell object. You should use at least initWithStyle:. And take a look how to use dequeueReusableCellWithIdentifier:forIndexPath:. A typical implementation would look like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
// Reuse/create cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Update cell contents
cell.textLabel.text = #"Your text here";
cell.detailTextLabel.text=#"text did appear";
return cell;
}
I can't believe I've been doing XCode programming for two years, and still hit this issue.
I had the same problem with XCode 6.1 - I was setting my UITableView's delegate & dataSource in the viewWillAppear function, but none of the delegate functions were kicking in.
However, if I right-clicked on the UITableView on the Storyboard, the circles for delegate and dataSource were empty.
The solution, then, is to hold down the CTRL key, and drag from each of these circles up to the name of your UIView which contains your UITableView:
After doing this, my UITableView happily populated itself.
(So, we're upto v6.1 of XCode now are we ? Do you think Apple ever going to make this thing, you know, friendly...? I would quite like to add a Bookmark in my code... that'd be a nice feature.)

Resources