Popover in UITableViewcell not coming immediately . - ios

i have a dynamic tableviewcontroller SideBarTableViewController.m/.h .
Have a pop up view controller - popUpViewController.m/.h
Have subclassed a cell of SideBarTableViewController -> RegisterTableViewCell.m/.h and added a button outlet from the cell to it.
Have connected the cell to popUpViewController in storyboard using "present As popover" segue and the segue is given identifier "popover". The anchor point in storyboard has been set to Tableview for now , changing it later in preparesegue .
RegisterTableViewCell.h
#property (weak, nonatomic) IBOutlet UIButton *PopoverAnchorButton;
SideBarTableViewController.m
#import "RegisterTableViewCell.h"
(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:#"popover"] && segue.destinationViewController.popoverPresentationController){
UIPopoverPresentationController *popController = segue.destinationViewController.popoverPresentationController;
popController.sourceView = sender;
RegisterTableViewCell *cell = [[RegisterTableViewCell alloc]init];
segue.destinationViewController.popoverPresentationController.sourceRect = CGRectMake(cell.PopoverAnchorButton.frame.size.width/2, cell.PopoverAnchorButton.frame.size.height, 0, 0);
popController.delegate = self;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier = [menuItems objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
RegisterTableViewCell *regcell = [[RegisterTableViewCell alloc]init];
[regcell.PopoverAnchorButton addTarget:self action:#selector(PresentPopover:) forControlEvents:UIControlEventTouchUpInside];
// Configure the cell...
return cell;
}
-(void) PresentPopover:(UIButton *)sender
{
NSLog(#"present popover called ");
[self performSegueWithIdentifier:#"popover" sender:sender];
}
popUpViewController.m
- (IBAction)closeview:(id)sender {
[self.view removeFromSuperview];
}
Problem:
The popup is displayed from the left end of the cell, but wat i see , there is a delay in popup presentation . Normally , first click in the cell, popup comes up as expected ,
second click -> little delay ,
third -> little more delay ... (delay not always increasing though, but fixed 6-7 seconds )
let the ipad be idle for say 6 seconds , and again click in the cell, popup shows immediately .
double clicking(2 taps ) in the cell displays it immediately but with a warning :
2016-07-11 22:53:05.462 Player-app_03[1947:590814] Warning: Attempt to present <UINavigationController: 0x125026400> on <SideBarTableViewController: 0x124d258f0> which is already presenting (null)
What is happening here ? i am clueless. Anybody please help.

The problem is likely to be found in the actions of the segue.destinationViewController, which, from the OP code, appears itself to handle another view controller. To get a handle on this, omit the prepareForSegue logic that you have, and omit anything in the destination vc's viewDidLoad or viewWillAppear that is related to vc presentation.
The segue.destinationViewController is the view controller that's going to get presented. Anything that messes with that is asking for trouble.
The increasing lag time is very likely caused by the action (inaction, rather) in closeview, which is merely removing the popup view controller's view, leaving the view controller itself around indefinitely. The proper action in that method is to call:
[self dismissViewControllerAnimated:YES completion:nil];
Also, please note that any place you directly allocate a table view cell (done twice in the OP code), is indicative of at least a misunderstanding, and probably a mistake.

Related

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];
}

Reload UIViewController in "viewDidLoad"

I change the value of 2 UILabels in my "viewDidLoad" method, but I need the view to refresh after that in order to display the values. As it currently stands, the UILabels display the value of the previously selected cell. I need to do the refresh right after I change the labels' values. The "setNeedsDisplay" method is not doing the job.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_nameLabel.text = _selectedLocation.name;
_addressLabel.text = _selectedLocation.address;
[self.view setNeedsDisplay];
}
Based on your comments, I think you are trying to do something like:
- (void)updateLabelTexts {
_nameLabel.text = _selectedLocation.name;
_addressLabel.text = _selectedLocation.address;
}
and wherever you are changing the _selectedLocation values:
//Just an example
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
_selectedLocation = _yourLocationsArray[indexPath.row];
//now you call your update method
[self updateLabelTexts];
}
The point is that you have to call [self updateLabelTexts]; just after you update the values.
A very stupid bug. Turns out when I made the segue to transition into the next view, I actually dragged it from a physical cell on to the destination controller. However, I should've simply connected the sending uiview controller to the destination viewcontroller with the segue, and then manually handled the transition. That fixed it, so there's no need to "refresh or reload" the UIView as I was trying to do.

Call ViewController inside UITableViewCell

I have a ViewController wich have a UItableView.
Inside every cell in this TableView I have a subview.
In the first row of my TableView I have a subview that contains 2 buttons.
I want that when one of those buttons are pressed, my UINavigationController pushes my secondViewController on the screen.
But nothing happens, I don't get any errors, just don't happen!
I already try everything I now, but nothing seems to work.
Here is my code at my AppDelegate.m
firstViewController * firstView = [firstViewController new];
UINavigationController * navViewController = [[UINavigationController alloc]initWithRootViewController:firstView];
self.window.rootViewController = navViewController;
In my firstViewController I have my TableView:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * CellIdentifier = #"Cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.section == 0 && indexPath.row == 0) {
[cell.contentView addSubview:_actionBar];
}
else {
for (UIView * view in cell.contentView.subviews) {
[view removeFromSuperview];
}
_feed = [[Y_feedViewController sharedFeed]getViewWithThisInfo:[_arrayOfFeeds objectAtIndex:indexPath.section]];
[cell.contentView addSubview:_feed];
}
return cell;
}
So, the Buttons are in my _actionBar (that I add as a subview in my first row), and when I press the Button01 I want to call my secondViewController
Man, I already try everything, but can't work with this.
I already try to call the pushViewController: from my _actionBar, my TableViewController, my firstViewController, etc.
Thanks.
It's not clear how you are assigning an action to the buttons in _ActionBar. I think it would be easier and cleaner to use two different cell types, one of which has the buttons in it (rather than adding a subview in code). Just dequeue the one you want based on the indexPath. When you dequeue the one for the first row, add the action and target for your buttons (with the target being the view controller).

iOS TableViewController in PopOver disappears after touching tableview

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.

prepareForSegue getting called twice, with Attempt to present <UINavigationController> while presentation is in progress

I am new to ios programming and asking here, but I visit all the time! I am stumped at why I am getting this problem, it compiles with no errors and I have checked and checked all my outlets and identifiers in my MainStoryboard.
I have 2 UITableViewControllers, I am passing a string from the first to the second when the user selects an item in the table, so in
FirstTableViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
int sel = indexPath.row;
if (sel == 0) {
_keyName = [NSString stringWithString:_string1];
NSLog(#"the table was selected at cell 0, %#", _string1);
}
if (sel == 1) {
_keyName = [NSString stringWithString:_string2];
}
// more code below...
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ResultsSegue"])
{
UINavigationController *navigationController = segue.destinationViewController;
ResultsViewController *rv = [[navigationController viewControllers] objectAtIndex:0];
[rv setResults: _keyName];
NSLog(#"in the progress view, %#", _keyName);
//rv.delegate = (id)self;
rv.delegate = self;
}
}
And in my ResultsViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"in the results, %#", _results);
NSLog(#"in the results view");
}
In the NSlog readout I get:
...
in the progress view, (null)
in the results, (null)
in the progress view, The Right String
Warning: Attempt to present on
Then when I hit the cancel button to return to the firstTableview and press the detail view again it no longer shows null..
in the progress view, The Right String
in the results, The Right String
in the progress view, The Right String
The problem is prepareForSegue is called before didSelectRowAtIndexPath. You should just eliminate the didSelectRowAtIndexPath method, and do everything in prepareForSegue. You can use the following line to get the indexPath you need:
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
Rob's answer helped me, as well - thanks! I'm coding in Swift, so for those who run into this while Swifting, here's how to get the index (or index row) clicked on in Swift 3:
var rowClicked = (self.tableView.indexPathForSelectedRow?.row)!
May be your segue is connection start form the table view cell instead of view controller.
I had same issue I removed the segue from the table view cell and added back at view controller level.

Resources