Close popover by clicking UIButton in popover that created from program - ios

I have a UIButton in tableViewCell that perform
-(IBAction)buttonClicked:(id)sender{
UIStoryboard *SB = [UIStoryboard storyboardWithName:#"ABC" bundle:nil];
UIViewController *VC = [SB instantiateViewControllerWithIdentifier:#"someID"];
popoverController = [[UIPopoverController alloc] initWithContentViewController:VC];
[popoverController setDelegate:self];
..............................
[popoverController presentPopoverFromRect:rect
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionRight
animated:YES];
}
to popover a controller which consist of a UITextField and a UIButton. Now I'm going to pass back the string in UITextField from the popover controller by clicking the UIButton?

retain this view controller in in .h
UIViewController *VC;
change this
UIViewController *VC = [SB instantiateViewControllerWithIdentifier:#"someID"];
to
self.VC = [SB instantiateViewControllerWithIdentifier:#"someID"];
It will be deallocated from the memory when the .h object destroyed from memory.
When you dismiss the popover, still the last popover exists and you can access like
VC.yourTextField.text
When you present again on popover make sure to empty the text field to empty by setting #"".

If you are using a TableView with your custom TableViewCell you can create a method in your TableViewCell class for when you push your button:
CustomTableViewCell.h
#interface CustomTableViewCell : UITableViewCell
#property (nonatomic, strong) IBOutlet UIButton *cellButton;
#property (nonatomic, strong) IBOutlet UITextField *cellTextField;
- (NSString*)getText;
#end
CustomTableViewCell.m
- (NSString*)getText {
return self.cellTextField.text;
}
And in your CustomTableView class:
CustomTableView.m
in delegate method of your CustomTableView set self as delegate to your CustomTableViewCell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomTableViewCell *cellCustom = [tableView dequeueReusableCellWithIdentifier:#"CustomTableViewCell"];
...
[cellCustom.cellButton setTag:indexPath.row];
...
return cell;
}
And finally in your IBAction method of your button:
- (IBAction)pushButton:(id)sender{
UIButton *btn = (UIButton*)sender;
CustomTableViewCell *cellSelected = (CustomTableViewCell *)[self.tableView cellForRowAtIndexPath:btn.tag];
NSString *strWritten = [cellSelected getText];
NSLog(#"Text written: %#", strWritten);
}

Related

How to pass data from view controller to UICollectionReusableView

I have 2 viewcontrollers (A and B). When i click on selected record in VC A, it will redirect to VC B. In my VC B, i have UICollectionReusableView to display header for details.
May i know how to pass data from VC A to VC B UICollectionReusableView? Attached herewith my code :-
VC A (I able to get value in NSLog here)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
Merchant_TableViewCell *cell=[tableView cellForRowAtIndexPath:indexPath];
//Link to Shop page
MerchantDetail_ViewController *MerchantDetail_ViewControl = [[MerchantDetail_ViewController alloc] init];
MerchantDetail_HeadView *MerchantDetail_Head = [[MerchantDetail_HeadView alloc] init];
MerchantDetail_Head.strName = cell.nameLabel.text;
NSLog(#"strname - %#",MerchantDetail_Head.strName);
[self.navigationController pushViewController:MerchantDetail_ViewControl animated:YES];
}
In VC B UICollectionReusableView .h file
#interface MerchantDetail_HeadView : UICollectionReusableView
#property (nonatomic, retain) IBOutlet NSString *strName;
#property (nonatomic, retain) IBOutlet NSString *strImage;
In VC B UICollectionReusableView .m file (NSLog here will get null value)
- (void)awakeFromNib {
[super awakeFromNib];
self.headImageButton.clipsToBounds = YES;
self.headImageButton.layer.cornerRadius = 30;
self.nickNameLabel.text = strName;
NSLog(#"Head View - %#",strName);
}
Any idea? Please help thx.

Pushing new UIViewController from custom UIPopOver issue

Hello I'm using this library to show my PopOver which contain tableView with searchBar.
The problem is that one user try to select row from the tableView instead dismissing the popOver and displaying the slected row in hole screen I got this :
.
I've tried to use [self.parentViewController.navigationController ...] to push my view but didn't worked.
This is my popOver code (in MainVC.h):
-(IBAction)showPopoverSearch:(id)sender{
UIBarButtonItem *btn = (UIBarButtonItem *) sender;
NSInteger width = 600;
NSInteger height = 400;
SearchViewController *searchVC = [self.storyboard instantiateViewControllerWithIdentifier:#"searchView"];
searchVC.modalInPopover = NO;
UINavigationController* contentViewController = [[UINavigationController alloc] initWithRootViewController:searchVC];
popoverController = [[WYPopoverController alloc] initWithContentViewController:contentViewController];
popoverController.delegate = self;
//popoverController.passthroughViews = #[btn];
popoverController.popoverContentSize = CGSizeMake(width, height);
popoverController.popoverLayoutMargins = UIEdgeInsetsMake(10, 10, 10, 10);
popoverController.wantsDefaultContentAppearance = YES;
[popoverController presentPopoverFromBarButtonItem:btn permittedArrowDirections:WYPopoverArrowDirectionAny animated:YES];
}
And this is the didSelctRow method (SearchViewController.m) :
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main"bundle:nil];
PostReaderViewController *postReaderView =
(PostReaderViewController *)
[storyboard instantiateViewControllerWithIdentifier:#"postReader"];
postReaderView.thePost = [_postsArray objectAtIndex:indexPath.row];
// if ([self.parentViewController.po .popoverController isPopoverVisible])
// [popoverController dismissPopoverAnimated:YES];
[self.navigationController pushViewController:postReaderView animated:YES];
}
To solve this issue I've passed the Navigation controller and popoverController from The parent View MainVC.h to child controller SearchViewController.h and then use those vars to dismiss my PopOvercontroller and push the new VC. Code snippet :
SearchView
#interface SearchViewController : UIViewController
#property (strong, nonatomic) WYPopoverController *parentPopoverVC;
#property (strong, nonatomic) UINavigationController *parentNavigationController;
#end
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
...
[self.parentPopoverVC dismissPopoverAnimated:YES];
[self.parentNavigationController pushViewController:postReaderView animated:YES];
}
MainVC.h
-(IBAction)showPopoverSearch:(id)sender{
SearchViewController *searchVC = [self.storyboard instantiateViewControllerWithIdentifier:#"searchView"];
[searchVC setParentPopoverVC:popoverController];
[searchVC setParentNavigationController:self.navigationController];
[popoverController presentPopoverFromBarButtonItem:btn permittedArrowDirections:WYPopoverArrowDirectionAny animated:YES];
}

ipad-how to open a popup view controller in a UITableViewCell

These are the files I am working on:
ChecklistViewController.h
ChecklistViewController.m
ChecklistTableViewCell.h
ChecklistTableViewCell.m
ChecklistTableViewCell.xib
DetailViewController.h
DetailViewController.m
DetailViewController.xib
I have a ChecklistViewController which displays a UITableView. Because I needed a different layout for the UITableViewCell, I have subclass UITableViewCell. I have created a nib file ChecklistTableViewCell.xib which has a UITableViewCell that contains a label, button and switch view. i have linked the UITableViewCell to a custom class ChecklistTableViewCell.
I have linked up the necessary outlets from the nib file to ChecklistTableViewCell class, and in ChecklistViewController cellForRowAtIndexPath I'm able to display label text.
In the UITableViewCell class file ChecklistTableViewCell, I have also linked and implemented a IBAction method that will be called when the button is clicked. When this method is called, how do I open DetailViewController as a popup?
Here is the snippet of my IBAction method:
-(IBAction)showPopup:(id)sender
{
NSLog(#"popup");
DetailViewController *vp = [[DetailViewController alloc] init];
vp.modalPresentationStyle = UIModalPresentationFormSheet;
vp.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
vp.view.superview.frame = CGRectMake(0, 0, 540, 620);
}
rdelmar is spot on with his comment. Because presentViewController:animated:completion is a method in the view controller, your ChecklistTableViewCell needs to make the view controller aware of the button click.
You have 2 choices:
Assuming your data source is your view controller, in your view controller:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ChecklistTableViewCell *cell = ...;
cell.button.tag = indexPath.row; // or whatever appropriate
[cell.button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
- (void)buttonTapped:(UIButton *)button
{
DetailViewController *vc = ...; // get your "popup" accordingly using button.tag
[self presentViewController:vc animated:YES completion:nil];
}
Or you can declare a protocol that your view controller adheres to:
// ChecklistTableViewCell.m
#protocol ChecklistTableViewCellDelegate
- (void)buttonTapped:(ChecklistTableViewCell *)sender;
#end
#implementation ChecklistTableViewCell : UITableViewCell
{
...
- (IBAction)showPopup:(id)sender // maybe change the name to something more appropriate
{
if ([self.delegate respondsToSelector:#selector(buttonTapped:)])
{
[self.delegate buttonTapped:self];
}
}
...
}
// ChecklistViewController.m
#implementation ChecklistViewController : ChecklistTableViewCellDelegate
{
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ChecklistTableViewCell *cell = ...;
cell.tag = indexPath.row; // or whatever appropriate
cell.delegate = self;
...
return cell;
}
- (void)buttonTapped:(ChecklistTableViewCell *)sender
{
DetailViewController *vc = ...; // get your "popup" accordingly using sender.tag
[self presentViewController:vc animated:YES completion:nil];
}
...
}
If you want to show a detail view controller as pop up in iPad there is a control called UIPopoverController.
How to use UIPopoverController?
In .h file
UIPopoverController *popoverController;
In .m file
DetailviewController * objViewController = [[DetailviewController alloc]initWithNibName:#"DetailviewController" bundle:nil];
obj.delegate = (id )self; // if DetailViecontroller has any delegate.
popoverController = [[UIPopoverController alloc] initWithContentViewController:objViewController];
popoverController.popoverContentSize = CGSizeMake(320.0, 400.0);
UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:theRow inSection:1]];
CGRect rect=CGRectMake(cell.bounds.origin.x+600, cell.bounds.origin.y+10, 50, 30);
[popoverController presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

UILabel isn't added to view

I have two viewControllers where one of them contains a UILabel and a UIButton, and the other one a UITableView. When the UIButton in the first view is pressed the new ViewController is presented and when a row in the tableview is selected the tableview is dismissed and the UILabel in the first viewController should be updated so its text is the same as the cell name tapped in the tableview.
Code:
In the first Viewcontroller:
- (void)changeTitleWithString:(NSString *)title
{
UILabel* selected_station = [[UILabel alloc ]initWithFrame:CGRectMake(45, 153+45, 231, 20)];
[selected_station setFont:[UIFont systemFontOfSize:16.0]];
selected_station.textAlignment = NSTextAlignmentCenter;
selected_station.text = [NSString stringWithFormat:#"%#", title];
[self.view addSubview:selected_station];
NSLog(#"%#", selected_station);
NSLog(#"%#", title);
}
In second viewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.currentString = [NSString stringWithFormat:#"Cell %d", indexPath.row+1];
NewViewController *viewCOntroller = [[NewViewController alloc] init];
[viewController changeTitleWithString:self.currentString];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
The changeTitleWithString function is called and the string from tableview is successfully received in the function, but the UILabel won't show up. When I log out the UILabel (selected_station) it's not nil and its text is correct. Why doesn't the string show up on the view?
This does not look like you are referencing back to a previous allocated view controller (NewViewController). Rather you are allocating a new NewViewController.
A better approach might be to create a delegate protocol for the second view controller and make the NewViewController it's delegate --
So create a second view controller with a delegate property.
something like this
#protocol SecondViewControllerDelegate;
#interface SecondViewController : UIViewController
#property (nonatomic, strong) NSString *currentString;
#property (nonatomic, assign) id<SecondViewControllerDelegate>delegate;
#end
//----------------------------------------------------------------------------------
#protocol SecondViewControllerDelegate <NSObject>
#optional
-(void) secondViewController:(SecondViewController*)secondViewController didChangeSelectionText:(NSString *)string;
#end
Now in the implementation of the SecondViewController do something like this
#implementation SecondViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.currentString = [NSString stringWithFormat:#"Cell %ld", indexPath.row+1];
if ([self.delegate respondsToSelector:#selector(secondViewController:didChangeSelectionText:)]) {
[self.delegate secondViewController:self didChangeSelectionText:self.currentString];
}
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
#end
Now in the implementation of the FirstViewController (your NewViewController) do something like this
#implementation FirstViewController
-(void) showSecondController
{
SecondViewController *viewController = [[SecondViewController alloc] init];
[viewController setDelegate:self]; // set this controller as the delegate
// add the rest of the display code here
}
#pragma mark - SecondViewControllerDelegate Methods
-(void) secondViewController:(SecondViewController*)secondViewController didChangeSelectionText:(NSString *)string
{
//change your text here
}
#end
This should be enough to get you pointed in the right direction
In FirstViewController
- (void)changeTitleWithString:(NSString *)title :(UIView *)labelView
{
UILabel* selected_station = [[UILabel alloc ]initWithFrame:CGRectMake(45, 153+45, 231, 20)];
[selected_station setFont:[UIFont systemFontOfSize:16.0]];
selected_station.textAlignment = NSTextAlignmentCenter;
selected_station.text = title;
[labelView addSubview:selected_station];
NSLog(#"%#", selected_station);
NSLog(#"%#", title);
}
InSecondViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.currentString = [NSString stringWithFormat:#"Cell %d", indexPath.row+1];
NewViewController *viewCOntroller = [[NewViewController alloc] init];
[viewController changeTitleWithString:self.currentString:self.view];
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
I hope it helps

delegate method from popover not called?

edit: solved. see my comment why.. sorry this mess, not able to post an answer myself yet as a newbie..
iPad App: I have a table view and instantiate from the accessoryView a popover with another tableview. in the popover I want to select a cell and pass that index back to the rootView.
I implemented a protocol in PopoverController and conform RootViewController to it.
Why is that backPopover method in the root view not being called?
Any hint much appreciated!!
Edit: That storyboard reference points to a navigation controller. The popover itself works fine..
RootViewController.h
#import "PopoverViewController.h"
#interface rootViewController : UITableViewController <UIPopoverControllerDelegate, UITableViewDelegate, AddDelegate>
{
UIPopoverController *popOverController;
}
#property (nonatomic, retain) UIPopoverController *popOverController;
#property (nonatomic) PopoverContent *popoverContent;
RootView.m
-(void) backPopover:(int)index
{
NSLog(#"index sent:%i", index);
[popOverController dismissPopoverAnimated:YES];
}
// accessoryView Button
- (void) popOver:(UIButton*)paramSender
{
UITableViewCell *cell = (UITableViewCell*)paramSender.superview;
if (cell != nil)
{
//Table position for popover
UIButton *button = (UIButton *)cell.accessoryView;
if(![self popoverContent])
{
popoverContent = [[self storyboard]instantiateViewControllerWithIdentifier:#"PopoverContent"];
[popoverContent setDelegate:self];
popOverController = [[UIPopoverController alloc]initWithContentViewController:popoverContent];
popOverController.popoverContentSize = CGSizeMake(320.0, 600.0);
[popOverController setDelegate:self];
}
CGRect rect = button.frame;
[popOverController presentPopoverFromRect:rect inView:cell permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
PopoverController.h
#protocol AddDelegate <NSObject>
- (void)backPopover: (int)index;
#end
#property (nonatomic, weak) id <AddDelegate> delegate;
PopoverController.m
#synthesize delegate;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.delegate backPopover:indexPath.row];
}
Please try this.
MyViewController *viewController=[[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
UIPopoverController* aPopover = [[UIPopoverController alloc]
initWithContentViewController:popupController];
The problem was that storyboard reference, it actually pointed to a navigation controller. Above code works like a charm.

Resources