Dismiss UIPopoverController on didSelectRowAtIndexPath - iphone

I have implemented UIPopoverController with storyboard but i am not able to make it dismiss when I select particular row in UITableView.
When select particular row so that time I want to dismiss the popover but I am not able dismiss it.
I write below code for this:
//Show the popover in Main UIViewController
-(IBAction)clickNotes:(id)sender {
NSLog(#"notes:");
NoteList *objNoteList = [[NoteList alloc] initWithNibName:#"NoteList" bundle:nil];
popover.delegate = self;
popover = [[UIPopoverController alloc] initWithContentViewController:objNoteList];
popover.popoverContentSize = CGSizeMake(250, 450);
[popover presentPopoverFromRect:CGRectMake(730, 0, 1,1) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
//Hide the popover in another UIViewController on didSelecteRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Notepad_ipad *objNote = [[Notepad_ipad alloc] init];
NSString *mSelectedNoteText = #"Selected text";
[objNote SelectedNote:mSelectedNoteText];
[objNote.popover dismissPopoverAnimated:YES];
}

use
[popover dismissPopoverAnimated:YES];

The following code instantiates a NEW Instance. So it has nothing to do with the already existing popover :Notepad_ipad *objNote = [[Notepad_ipad alloc] init];
Also Instead Of :
popover.delegate = self;
popover = [[UIPopoverController alloc] initWithContentViewController:objNoteList];
USE:
popover = [[UIPopoverController alloc] initWithContentViewController:objNoteList];
popover.delegate = self;
I.e.: Allocate the instance first and then set its delegate.
Finally replace your method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
with this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *) indexPath {
[popover dismissPopoverAnimated:YES];
}

// Create protocol in .h file of controller which contains didSelectRowAtIndexPath method as follows:
#protocol Popoverdelegate <NSObject>
{
-(void)didRowAtIndexPathIsSelected;
}
// Add this property in .h file of the same controller
#property (strong, nonatomic) id<Popoverdelegate> delegate;
// Now implement this protocol in interface which calls popovercontroller
// for ex: #interface ViewController <Popovercontroller>
// then add following properties to viewController .h file
#protocol (strong, nonatomic) UIPopoverController *popoverController;
// Implement popoverdelegate protocol in .m file as
- (void) didRowAtIndexPathIsSelected
{
[self.popoverController dismissPopoverAnimated:YES];
}
// Replace your code as follows
-(IBAction)clickNotes:(id)sender
{
NoteList *objNoteList = [[NoteList alloc] initWithNibName:#"NoteList" bundle:nil];
popover = [[UIPopoverController alloc] initWithContentViewController:objNoteList];
popover.delegate = self;
self.popoverController = popover;
self.popoverController.popoverContentSize = CGSizeMake(250, 450);
[self.popoverController presentPopoverFromRect:CGRectMake(730, 0, 1,1) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Notepad_ipad *objNote = [[Notepad_ipad alloc] init];
NSString *mSelectedNoteText = #"Selected text";
[objNote SelectedNote:mSelectedNoteText];
[self.delegate dismissPopoverAnimated:YES];
}

The smartest thing to do here (imho) is to follow this example code, I do it every time:
// firstViewController.h
#interface firstViewController : UIViewController <SecondDelegate>
{
SecondViewController *choice;
}
// firstViewController.m
- (void)choicePicked(NSString *)choice
{
NSLog(choice);
[_popover dismissPopoverAnimated:YES]; //(put it here)
_popover = nil; (deallocate the popover)
_choicePicker = nil; (deallocate the SecondViewController instance)
}
// secondViewController.h (the one that will give back the data)
#protocol SecondDelegate <NSObject>
- (void)choicePicked:(NSString *)choice;
#end
#interface secondViewController : UITableViewController
#property (nonatomic, assign) id <SecondDelegate> delegate;
#end
// secondViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *selection = [_yourArray objectAtIndex:indexPath.row];
[[self delegate] choicePicked:selection];
}

Related

can not setimage of uiimageview while pushing viewcontroller

I am new on objective c and I am trying to set image of UIImageview while pushing viewcontroller
I checked other answer and I did the same way they said it but its not working for me below is my code and i will explain other things in it
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *svController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:[NSBundle mainBundle]];
UIImage *image = [UIImage imageNamed:#"default.png"];
UIImageView* imageview = [[UIImageView alloc] initWithImage:image];
id obj = [[mainArray valueForKey:#"image"] objectAtIndex:[indexPath row]];
if ([obj isKindOfClass:[NSString class]])
{
NSLog(#" image%#",image); //print this image<UIImage: 0xaa70700>
NSLog(#" image%#",svController.image); //print this image(null)
[[svController image] setImage: image];
NSLog(#" image%#",svController.image); //print this image(null)
}
else {
NSLog(#" image%#",svController.image);
[[svController image] setImage: [[mainArray valueForKey:#"image"] objectAtIndex:[indexPath row]]];
NSLog(#" image%#",svController.image);
}
[self.navigationController pushViewController:svController animated:YES];
[svController release];
svController = nil;
}
below is my detailviewcontroller
#interface DetailViewController : UIViewController{
UIImageView *image;
}
#property (retain, nonatomic) IBOutlet UIImageView *image;
its connected to Xib and i have synthesized it
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
name.text = nameString;
email.text = emailString;
NSLog(#"%#",image); // print this <UIImageView: 0x9d73950; frame = (27 35; 204 181); autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x9db4050>>
}
its working perfectly when i send NSString and set them on my lable but not working for image it its so small thing but now i dont know what to do please help
hear is the simple way, i am showing the example that u can set image in detail view controller
in your master view controller
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 0)//for 1st row
{
DetailViewController *detController = [[DetailViewController alloc]initWithNibName:#"DetailViewController" bundle:nil];
detController.detailImage = [UIImage imageNamed:#"abc.png"];//setting the property for image
[self.navigationController pushViewController:detController animated:YES];
[detController release];//im doing without ARC
}
else if (indexPath.row == 1)
{
DetailViewController *detController = [[DetailViewController alloc]initWithNibName:#"DetailViewController" bundle:nil];
detController.detailImage = [UIImage imageNamed:#"123.png"];
[self.navigationController pushViewController:detController animated:YES];
[detController release];//im doing without ARC
}
}
and in your detail view controller
// .h file
#interface DetailViewController : UIViewController
{
}
#property (retain, nonatomic) IBOutlet UIImageView *ImageView;
#property (nonatomic, retain)UIImage * detailImage;//set a property for image that u are passing from master viewcontroller
#end
//in .m file
#implementation DetailViewController
#synthesize detailImage; //synthesise it
// and in viewDidload method
- (void)viewDidLoad
{
[super viewDidLoad];
//set your passed image to image view
self.ImageView.image = self.detailImage;
}
Better would be just do like this:
[self.navigationController pushViewController:svController animated:YES];
if(yourImage) //got UIImage reference then only set it
svController.yourImgView.image = yourImageHere
.................
<<Another code here>>
..............
Thats it....
You can't do this, because svController's view has not been loaded at the time you try to set the image of its image view (so the image view will be null).
You need to pass the image itself to a property you create in svController, and set the image in svController's viewDidLoad method.
Set your UI object intialization afer pushing view controller.
[self.navigationController pushViewController:svController animated:YES];
//set image here
Reason is viewDidLoad of svController will not be called and loaded yet and imageview will not have reference yet.
EDIT :
Better would be just do like this:
[self.navigationController pushViewController:svController animated:YES];
if(yourImage) //got UIImage reference then only set it
svController.yourImgView.image = yourImageHere
.................
<<Another code here>>
..............
Thats it....

iphone - PushViewController does not work With Reveal Controller

I am creating an iphone application, where i have number of grid views in a main view controller class. So, i want when i select a grid cell from main view, should load a Reveal controller. The layout looks like
I have the following code in my Main View Controller.
-(void) gridView:(UzysGridView *)gridView didSelectCell:(UzysGridViewCell *)cell
atIndex:(NSUInteger)index
{
if (index == 0){
FrontViewController *frontViewController = [[FrontViewController alloc]
init];
RightViewController *rightViewController = [[RightViewController alloc] init];
UINavigationController *frontNavigationController = [[UINavigationController alloc]
initWithRootViewController:frontViewController];
SWRevealViewController *mainRevealController = [[SWRevealViewController alloc]
initWithRearViewController:nil
frontViewController:frontNavigationController];
mainRevealController.delegate = self;
self.revealController.rightViewController = rightViewController;
self.revealController = mainRevealController;
[self.navigationController pushViewController:self.revealController animated:YES];
}
here in main view controller .h file,
#property (strong, nonatomic) SWRevealViewController *revealController;
Also i have declare SWRevealViewControllerDelegate. Problem is that this self.revealController doesn't load/show. I have tried with App Delegate also, but nothing works.
thanks.
I solved it: Use the below code..
-(void) gridView:(UzysGridView *)gridView didSelectCell:(UzysGridViewCell *)cell
atIndex:(NSUInteger)index {
if (index == 0){
FrontViewController *frontViewController = [[FrontViewController alloc]
init];
myNavigationController = [[UINavigationController alloc]
initWithRootViewController:frontViewController];
SWRevealViewController *revealController = [[SWRevealViewController alloc]
initWithRearViewController:nil frontViewController:myNavigationController];
revealController.delegate = self;
RightViewController *rightViewController =
[[RightViewController alloc] init];
rightViewController.view.backgroundColor = [UIColor greenColor];
revealController.rightViewController = rightViewController;
self.viewController1=revealController;
[self presentViewController:self.viewController1 animated:YES completion:nil];
}
}
And in Class.h file
#property(nonatomic, strong) UINavigationController *myNavigationController;
#property(nonatomic, strong) SWRevealViewController *viewController1;

Two table view in one view controller - pushing any view controller is not working

I have two table view in one view controller.
They works great! But they are not pushing to any vc.
Under -(void) viewDidLoad method in my main view controller:
horizontalViewController = [[HorizontalViewController alloc] init];
verticalViewController = [[VerticalViewController alloc] init];
[horizontalTableView setDataSource:horizontalViewController];
[verticalTableView setDataSource:verticalViewController];
[horizontalTableView setDelegate:horizontalViewController];
[verticalTableView setDelegate:verticalViewController];
horizontalViewController.view = horizontalViewController.tableView;
verticalViewController.view = verticalViewController.tableView;
What can I do?
Thanks.
refer a following code. If you want use a pushViewController method.
You must be have a NavigationViewController.
so, your structure is a little complex. one ViewController has number of Two TableViewController. one ViewController is not have NavigationController. NavigaitonViewController necessarily belong to the app when it runs because it should be configured.
TwoTableViewsAppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UINavigationController *naviController = [[[UINavigationController alloc] initWithRootViewController:viewController] autorelease];
[window setRootViewController:naviController];
[window makeKeyAndVisible];
return YES;
}
TwoTableViewsViewController.m
- (void)viewDidLoad {
if (firstController == nil) {
firstController = [[FirstTVContoller alloc] init];
}
if (secondController == nil) {
secondController = [[SecondTVController alloc] init];
}
[firstTable setDataSource:firstController];
[secondTable setDataSource:secondController];
[firstTable setDelegate:firstController];
[secondTable setDelegate:secondController];
firstController.view = firstController.tableView;
secondController.view = secondController.tableView;
firstController.rootViewController = self;
secondController.rootViewController = self;
[super viewDidLoad];
}
FirstTVContoller.h , SecondTVController.h
#import <Foundation/Foundation.h>
#interface FirstTVContoller : UITableViewController <UITableViewDataSource, UITableViewDelegate>{
NSMutableArray *items;
}
#property (nonatomic, retain) UIViewController *rootViewController;
#end
FirstTVContoller.m , SecondTVController.m
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
VerticalDetailViewController *verticalDetailViewController = [[VerticalDetailViewController alloc] initWithNibName:#"VerticalDetailViewController" bundle:nil];
[[self.rootViewController navigationController] pushViewController:verticalDetailViewController animated:YES];
}

How to pass a value to anotherviewcontroller?

Hello everybody, I have a UITableView in a UIViewController. When a row in the table is tapped I am collecting the cell's text value and putting it in a string called localstringGValue.
I want to pass this string and display it in another, viewController, but without using -pushViewController: I want this value to be stored somewhere like NSUserDefaults or NSDictonary and then, on viewWillapper of the other view controller I want this stored value to be displayed in a label.
in my .h:
NSString *localStringGValue;
in my .m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
localStringGValue = [tableView cellForRowAtIndexPath:indexPath].textLabel.text;
}
in my other view controller:
-(void)viewWillAppear
{
label.text=localStringGValue;
}
Thanks in advance.
save to nsuserdefaults:
[[NSUserDefaults standardUserDefaults] setObject:localstringGValue forKey:#"localstringGValue"];
[[NSUserDefaults standardUserDefaults] synchronize];
retrieve from nsuserdefaults:
NString *localstringGValue = [[NSUserDefaults standardUserDefaults] objectForKey:#"localstringGValue"];
Just use delegate. Before you push the 'UploadViewController' instance, you need set it's delegate as self(in GoogleDocMainPageController.m). Everytime, the tabel cell is selected, it'll set value for self.delegate(Here is GoogleDocMainPageController instance) by dispatching self.delegate's method, which is implemented by GoogleDocMainPageController:
[self.delegate setDataAfterSelectedTabelCell:[NSString stringWithFormat:#"TalbeCell %d selected", [indexPath row]]];
The main code is shown below:
UploadViewController.h:
#import <UIKit/UIKit.h>
#class UploadViewController;
#protocol UploadViewControllerDelegate <NSObject>
- (void)setDataAfterSelectedTabelCell:(NSString *)stringValueInCell;
#end
#interface UploadViewController : UITableViewController
#property (nonatomic, retain) id <UploadViewControllerDelegate> delegate;
#end
UploadViewController.m:
//...
#synthesize delegate = _delegate;
//...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.delegate setDataAfterSelectedTabelCell:[NSString stringWithFormat:#"TalbeCell %d selected", [indexPath row]]];
}
GoogleDocMainPageController.h:
#import <UIKit/UIKit.h>
#import "UploadViewController.h"
#class UploadViewController;
#interface GoogleDocMainPageController : UIViewController <UploadViewControllerDelegate>
- (void)loadUploadViewController;
#property (nonatomic, retain) UILabel * glLabel;
#property (nonatomic, retain) UploadViewController * uploadViewController;
#end
GoogleDocMainPageController.m:
//...
#synthesize glLabel = _glLabel;
#synthesize uploadViewController = _uploadViewController;
//...
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton * uploadButton = [[UIButton alloc] initWithFrame:CGRectMake(10.0f, 160.0f, 300.0f, 35.0f)];
[uploadButton setBackgroundColor:[UIColor blackColor]];
[uploadButton setTitle:#"Upload Button" forState:UIControlStateNormal];
[uploadButton addTarget:self action:#selector(loadUploadViewController) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:uploadButton];
[uploadButton release];
self.glLabel = [[UILabel alloc] initWithFrame:CGRectMake(10.0f, 200.0f, 300.0f, 35.0f)];
[self.glLabel setBackgroundColor:[UIColor blackColor]];
[self.glLabel setTextColor:[UIColor whiteColor]];
[self.glLabel setTextAlignment:UITextAlignmentCenter];
[self.glLabel setText:#"Default"];
[self.view addSubview:self.glLabel];
self.uploadViewController = [[UploadViewController alloc] initWithStyle:UITableViewStylePlain];
}
//...
#pragma mark -
- (void)loadUploadViewController
{
[self.uploadViewController setDelegate:self];
[self.navigationController pushViewController:self.uploadViewController animated:YES];
}
#pragma mark - UploadViewControllerDelegate
- (void)setDataAfterSelectedTabelCell:(NSString *)stringValueInCell
{
[self.glLabel setText:stringValueInCell];
}
Why don't you declare some #property(nonatomic,retain) and #synthesize it ? Then the getters/setters will be automatically created. Otherwise, define some getter/setters yourself.
Go through Following Steps-
In First ViewController -
Create Object of second ViewController
like SecondViewController *sec= [[SecondViewController alloc]init];
sec.myLable=#"My Lable String";
In Second ViewController -
In .h file
UILable *myLable;
#property(nonautomic,retain)IBOutlet UILable *myLable;
2.In .m file
#synthesize myLable;

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.