I'm trying to create a simple popup called Add Notes on a button click which has a save and cancel button to save the notes created by the user and to cancel the pop-up. This is pop-up classes
AddNotesPopUp.h
#import <UIKit/UIKit.h>
#import "UIImage+Buttons.h"
typedef enum AddNotesViewType
{
AddNotesPopUpSimple
}AddNotesPopUpType;
#protocol AddNotesDelegate<NSObject>
#optional
-(void)saveButtonClicked:(id) popUp;
-(void)cancelAddButtonClicked:(id)popUp;
#end
#interface AddNotesPopUp : UIView
#property AddNotesPopUpType atype;
#property (nonatomic,assign) id <AddNotesDelegate> delegate;
-(id)initWithDelegate:(id)parent type:(AddNotesPopUpType) type;
#property (weak, nonatomic) IBOutlet UIView *popView;
#property (strong, nonatomic) IBOutlet UIButton *titleButton;
#property (weak, nonatomic) IBOutlet UIButton *cancelAddButton;
#property (weak, nonatomic) IBOutlet UIButton *saveButton;
#property (weak, nonatomic) IBOutlet UITextView *textArea;
- (IBAction)saveButtonAction:(id)sender;
- (IBAction)cancelButtonAction:(id)sender;
-(void)show;
-(void)hide;
#end
AddNotesPopUp.m
#import "AddNotesPopUp.h"
#import <QuartzCore/QuartzCore.h>
#implementation AddNotesPopUp
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self=(AddNotesPopUp*)[[[NSBundle mainBundle] loadNibNamed:#"AddNotesPopUp" owner:nil options:nil] lastObject];
}
return self;
}
-(id)initWithDelegate:(id)parent type:(AddNotesPopUpType) type
{
if (self = [super initWithFrame:CGRectMake(0, 0, 300, 300)])
{
// Initialization code
self=(AddNotesPopUp*)[[[NSBundle mainBundle] loadNibNamed:#"AddNotesPopUp" owner:nil options:nil] lastObject];
}
self.delegate=parent;
self.atype=type;
UIViewController *parentView=(UIViewController*)parent;
[parentView.view addSubview:self];
if (type==AddNotesPopUpSimple)
{
[self.titleButton setImage:[UIImage buttonWithText:#"Add Notes" fontSize:15 bold:YES buttonSize:self.titleButton.frame.size baseColor:[UIColor colorWithRed:73.0/255.0 green:90.0/255.0 blue:100.0/255.0 alpha:1] downTo:[UIColor colorWithRed:57.0/255.0 green:70.0/255.0 blue:77.0/255.0 alpha:1]] forState:UIControlStateNormal];
[self.saveButton setImage:[UIImage buttonWithTextAlignCenter:#"Save" fontSize:15 bold:YES buttonSize:self.saveButton.frame.size baseColor:[UIColor colorWithRed:117.0/255.0 green:185.0/255.0 blue:83.0/255.0 alpha:1] downTo:[UIColor colorWithRed:95.0/255.0 green:144.0/255.0 blue:64.0/255.0 alpha:1]] forState:UIControlStateNormal];
[self.cancelAddButton setImage:[UIImage buttonWithTextAlignCenter:#"Cancel" fontSize:15 bold:YES buttonSize:self.cancelAddButton.frame.size baseColor:[UIColor colorWithRed:174.0/255.0 green:174.0/255.0 blue:174.0/255.0 alpha:1] downTo:[UIColor colorWithRed:124.0/255.0 green:124.0/255.0 blue:124.0/255.0 alpha:1]] forState:UIControlStateNormal];
}
self.popView.layer.masksToBounds=YES;
self.popView.layer.cornerRadius=5.0f;
self.popView.layer.borderWidth=1.0f;
self.popView.layer.borderColor=[[UIColor blackColor]CGColor];
self.popView.hidden=YES;
self.hidden=YES;
self.textArea.hidden=YES;
return self;
}
-(void)show
{
self.popView.hidden=NO;
self.textArea.hidden=NO;
[self.popView setTransform:CGAffineTransformMakeScale(0.1,0.1)];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.25];
[self.popView setTransform:CGAffineTransformMakeScale(1.0,1.0)];
[UIView commitAnimations];
}
-(void) hide
{
self.popView.hidden=YES;
}
- (IBAction)saveButtonAction:(id)sender {
[self.delegate saveButtonClicked:self];
}
- (IBAction)cancelButtonAction:(id)sender {
[self.delegate cancelAddButtonClicked:self];
}
#end
This is how I call the popup in my viewcontroller button action
- (IBAction)addNotes:(id)sender {
AddNotesPopUp *pop=[[AddNotesPopUp alloc] initWithDelegate:self type:AddNotesPopUpSimple];
[pop show];
}
I have checked with breakpoints and the execution goes successfully through the initwithDelegate and show methods in AddNotesPopUp.m but the pop-up doesnt appears, what am I missing here? I have added the delegates and classes of AddNotesPopUp in my viewcontroller and I dont receive any error either. I'm using Xcode 4.6. Any Suggestions?
Turns out it was a simple issue, I just needed to add
self.hidden=NO; in the show method
Related
I am attempting to create a UI programmatically. My problem is the view controllers subviews are not showing.
Here is how I am trying to create the UI:
.h
#import <UIKit/UIKit.h>
#protocol TimerCreatorDelegate <NSObject>
- (void)timerCreatorControllerDismissedWithString:(NSString *)timerName andTimeInterval:(NSTimeInterval)timeInterval;
#end
#interface TimerCreatorController : UIViewController {
// id timerCreatorDelegate;
}
#property (nonatomic, assign) id<TimerCreatorDelegate> timerCreatorDelegate;
#property (weak, nonatomic) UIDatePicker *timerLength;
#property (weak, nonatomic) UITextField *timerNameTextField;
#property (weak, nonatomic) UIButton *createTimerButton;
//#property (weak, nonatomic) IBOutlet UIDatePicker *timerLength;
//#property (weak, nonatomic) IBOutlet UITextField *timerNameTextField;
- (IBAction)createTimer:(id)sender;
#end
.m
#import "TimerCreatorController.h"
#interface TimerCreatorController ()
#end
#implementation TimerCreatorController
#synthesize timerCreatorDelegate;
#synthesize timerNameTextField;
#synthesize timerLength;
#synthesize createTimerButton;
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor grayColor];
timerNameTextField.placeholder = #"This timer is for:";
timerLength.datePickerMode = UIDatePickerModeCountDownTimer;
[createTimerButton setTitle:#"Start Timer" forState:UIControlStateNormal];
[createTimerButton setTitleColor:[UIColor colorWithRed:46/255 green:134/255 blue:53/255 alpha:1] forState:UIControlStateNormal];
createTimerButton.titleLabel.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:20];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (void)viewWillLayoutSubviews {
printf("viewWillLayoutSubviews Called.\n\n");
[self.view addSubview:timerLength];
[self.view addSubview:timerNameTextField];
[self.view addSubview:createTimerButton];
timerLength.translatesAutoresizingMaskIntoConstraints = false;
timerNameTextField.translatesAutoresizingMaskIntoConstraints = false;
createTimerButton.translatesAutoresizingMaskIntoConstraints = false;
timerLength.frame = CGRectMake(0, 0, self.view.frame.size.width, 216);
timerNameTextField.frame = CGRectMake((self.view.frame.size.width - 300) / 2, timerLength.frame.size.height + 40, 300, 30);
createTimerButton.frame = CGRectMake((self.view.frame.size.width - 96) / 2, timerNameTextField.frame.origin.y - 40, 96, 36);
[NSLayoutConstraint activateConstraints:[NSArray arrayWithObjects:
[timerLength.topAnchor constraintEqualToAnchor:self.view.topAnchor],
[timerLength.leftAnchor constraintEqualToAnchor:self.view.leftAnchor],
[timerLength.rightAnchor constraintEqualToAnchor:self.view.rightAnchor],
[timerLength.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[timerNameTextField.topAnchor constraintEqualToAnchor:timerLength.bottomAnchor],
[timerNameTextField.rightAnchor constraintEqualToAnchor:self.view.rightAnchor constant:-37],
[timerNameTextField.leftAnchor constraintEqualToAnchor:self.view.leftAnchor constant:37],
// [timerNameTextField.heightAnchor constraintEqualToAnchor:NSLayoutAttributeNotAnAttribute constant:30],
[createTimerButton.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
// [createTimerButton.widthAnchor constraintEqualToAnchor:NSLayoutAttributeNotAnAttribute constant:96],
// [createTimerButton.heightAnchor constraintEqualToAnchor:NSLayoutAttributeNotAnAttribute constant:36],
[createTimerButton.topAnchor constraintEqualToAnchor:timerNameTextField.bottomAnchor]
#warning Finish Layout Constraints
, nil]];
NSString *timerLengthString = [NSString stringWithFormat:#"%#", NSStringFromCGRect(timerLength.frame)];
NSString *timerNameTextFieldString = [NSString stringWithFormat:#"%#", NSStringFromCGRect(timerNameTextField.frame)];
NSString *createTimerButtonString = [NSString stringWithFormat:#"%#", NSStringFromCGRect(createTimerButton.frame)];
printf("timerLength: %s \n", [timerLengthString UTF8String]);
printf("timerNameTextFieldString: %s \n", [timerNameTextFieldString UTF8String]);
printf("createTimerButtonString: %s \n", [createTimerButtonString UTF8String]);
}
- (IBAction)createTimer:(id)sender {
if ([self.timerCreatorDelegate respondsToSelector:#selector(timerCreatorControllerDismissedWithString:andTimeInterval:)]) {
[self.timerCreatorDelegate timerCreatorControllerDismissedWithString:timerNameTextField.text andTimeInterval:timerLength.countDownDuration];
}
[self dismissViewControllerAnimated:true completion:nil];
}
#end
Despite me setting the frames of my views, the prints are showing frames of {{0,0},{0,0}}.
Where do you create the subviews? I see you trying to use them, but not where you are actually creating the objects you are using. Is it a .Nib file or are you actually doing everything programmatically? And why are your subviews weak references? If they are not held by anything else they will be released after they are created...
In Swift it will crash when you try to use an object before it is initialized. Objective-C is a little more forgiving and will just do nothing if you tell it to use a nil object (at least in the instances you are using).
Environment: IOS 8.02 Xcode 6
I have a form on a StoryBoard. It has 2 labels a text box and 2 buttons.
btnValidateAndSave disables all of the other controls on the form and calls a web service.
btnCance goes grey as if it has been disabled however it is clickable.
Below is the actual code behind the form.
#import "vcDigitalKeyManager.h"
#import "serviceManager.h"
#import "eziEnums.h"
#import "IsSystemLockedMethod.h"
#import "eziResponse.h"
#interface vcDigitalKeyManager ()
- (IBAction)btnValidateAndSave:(id)sender;
#property (strong, nonatomic) IBOutlet UITextField *txtDigitalKey;
#property (strong, nonatomic) IBOutlet UILabel *lblErrorMessage;
#property (strong, nonatomic) IBOutlet UIActivityIndicatorView *lblValidateActivity;
#property (strong, nonatomic) IBOutlet UIButton *btnValidateAndSave;
#property (strong, nonatomic) IBOutlet UIButton *btnCancel;
#property (strong, nonatomic) NSNumber *isWorking;
- (IBAction)btnCancel:(id)sender;
#end
#implementation vcDigitalKeyManager
#synthesize txtDigitalKey = _txtDigitalKey;
#synthesize lblErrorMessage = _lblErrorMessage;
#synthesize btnCancel = _btnCancel;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.lblValidateActivity setHidden:true];
}
- (IBAction)btnValidateAndSave:(id)sender {
[self.txtDigitalKey resignFirstResponder];
[self.txtDigitalKey setEnabled:NO];
[self.txtDigitalKey setUserInteractionEnabled:NO];
[self.lblValidateActivity setHidden:NO];
[self.btnValidateAndSave setEnabled:NO];
[self.btnValidateAndSave setUserInteractionEnabled:NO];
[self.txtDigitalKey setEnabled:NO];
[self.txtDigitalKey setUserInteractionEnabled:NO];
self.btnCancel.enabled=NO;
self.btnCancel.userInteractionEnabled = NO;
[self.lblValidateActivity startAnimating];
_isWorking = [NSNumber numberWithInt:1];
NSString * requestBody = [serviceManager buildSoapMessage:IsSystemLocked :self.txtDigitalKey.text ];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(displayEziResponse:)
name:#"kIsSystemLockedResponseNotification"
object:nil];
[[[IsSystemLockedMethod alloc]init] callNonPciMethod:requestBody servicetype:NonPci];
}
- (void) displayEziResponse:(NSNotification *) notification{
NSDictionary *userInfo = notification.userInfo;
eziResponse *myResponse = [userInfo objectForKey:#"someKey"];
if([myResponse.ErrorNumber isEqual:#"0"])
{
[self dismissViewControllerAnimated:YES completion:nil];
}
else
{
[self.lblErrorMessage setText:[NSString stringWithFormat:#"%#: %#",myResponse.ErrorNumber, myResponse.ErrorMessage]];
[self.lblErrorMessage setTextColor:[UIColor redColor]];
[self.lblErrorMessage setHidden:NO];
[self.lblValidateActivity stopAnimating];
[self.lblValidateActivity setHidden:YES];
[self.btnValidateAndSave setEnabled:YES];
[self.btnValidateAndSave setUserInteractionEnabled:YES];
[self.txtDigitalKey setEnabled:YES];
[self.txtDigitalKey setUserInteractionEnabled:YES];
[self.btnCancel setEnabled:YES];
[self.btnCancel setUserInteractionEnabled:YES];
}
}
- (IBAction)btnCancel:(id)sender {
//NSLog([NSString stringWithFormat:#"%d",NSStringFromBOOL(BOOL self.btnCancel.enabled)]);
if(_isWorking == [NSNumber numberWithInt:0])
{
[self dismissViewControllerAnimated:YES completion:nil];
}
//if(self.btnCancel.enabled)
}
#end
I have tested this in the simulator and on an iPhone 5S
Any Ideas how to actually disable the button?
Prefer also disabling user interaction on the button !
[self.btnCancel setUserInteractionEnabled:NO];
I found the issue and it was not actually the button that was the issue.
The Validate and Save button calls a function that does an async call to a web service.
I am using notifications to let the main thread know when the response has been received.
The notification was being sent back on the background thread. The affect of this was that the Cancel button was being enabled in real time but not the visual state.
I modified the code so the notification is sent back to the main thread and now everything updates on the main thread within 1 second.
I'm adding a subview the following way"
SettingsViewController *SVC = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:[NSBundle mainBundle]];
[self.parentViewController addChildViewController:SVC];
[self.view addSubview:SVC.view];
My subview is 300 x 360 and is centered on the screen. The problem occurs when I attempt to remove it (Getting released).
When I press the close button in this new view, I get exc bad access. What's the correct way to add my view? I have a SettingsViewController.xib linked up to a .h and .m file.
Here's what my close button in my settings view looks like:
-(IBAction)close:(id)sender {
[self.view removeFromSuperview];
[self removeFromParentViewController];
}
But even when I comment out everything inside, just triggering the button crashes the app.
This is what my .h file looks like:
#import <UIKit/UIKit.h>
#interface SettingsViewController : UIViewController
#property (nonatomic, strong) IBOutlet UIView *alertView;
#property (nonatomic, strong) IBOutlet UIButton *closeButton;
#property (nonatomic, strong) IBOutlet UILabel *musicLabel;
#property (nonatomic, strong) IBOutlet UILabel *soundFXLabel;
#property (nonatomic, strong) IBOutlet UILabel *vibrateLabel;
- (IBAction)close:(id)sender;
#end
and my implementation file:
#import "SettingsViewController.h"
#interface SettingsViewController ()
#end
#implementation SettingsViewController
#synthesize alertView;
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.alpha = 0;
self.alertView.layer.cornerRadius = 10.0f;
self.alertView.layer.borderColor = [UIColor whiteColor].CGColor;
self.alertView.layer.borderWidth = 4.0f;
self.closeButton.layer.cornerRadius = 5.0f;
self.closeButton.titleLabel.font = [UIFont fontWithName:#"SourceSansPro-Bold" size:20];
self.musicLabel.font = [UIFont fontWithName:#"SourceSansPro-Bold" size:30];
self.soundFXLabel.font = [UIFont fontWithName:#"SourceSansPro-Bold" size:30];
self.vibrateLabel.font = [UIFont fontWithName:#"SourceSansPro-Bold" size:30];
[UIView animateWithDuration:0.3
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.view.alpha = 1;
}
completion:^(BOOL finished){
//Display Players View
}];
}
- (IBAction)close:(id)sender {
//[self.view removeFromSuperview];
//[self removeFromParentViewController];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
And last but not least, here's a snapshot of my storyboard / xib order:
create a property for your SettingsViewController where you add & assign it where you create it.
// in .h file or private category on top
#property (nonatomic, strong) SettingsViewController *settingsController;
// your usual code + assigning controller
SettingsViewController *SVC = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:[NSBundle mainBundle]];
[self.parentViewController addChildViewController:SVC];
[self.view addSubview:SVC.view];
self.settingsController = SVC;
Side Note : the reason for this behavior is after the .view property of the ViewController is added to your view, the controller gets deallocated (only the .view is alive now). So when you try to hit the butons on view there is no SettingsViewController to callback those events, hence crash. When you create the property & assign it, the controller lives.
This question already has answers here:
Passing data between view controllers
(45 answers)
Closed 8 years ago.
What I have is menu at the top (vertical slider). On the top I have button, on clicking this button, the view will get scroll down and display the menu.
For this what I am doing is creating a view and showing it at top.
Now when I click on the button, I am planning to change the frame of top view with animation.
I am able to handle the frame and animation, however problem I am facing is setting the text to the right label and left button.
Below is the dropbox link to download the sample project. Any idea/ solution will be appreciated.
https://www.dropbox.com/s/pdaelw2k8ljnaki/TwoView.zip
What I tried is below code
CommonViewController *newClass = [[CommonViewController alloc] init];
newClass.parentObject = self;
NSLog(#"text is %#", newClass.rightSideLabel.text);
newClass.rightSideLabel.text = #"NEW VALUE HERE";
However still on the right side I see products only.
Full Code
CommonViewController.h
#import <UIKit/UIKit.h>
#interface CommonViewController : UIViewController
#property (retain, nonatomic) IBOutlet UIView *topView;
#property (retain, nonatomic) IBOutlet UILabel *rightSideLabel;
#property (retain, nonatomic) IBOutlet UIButton *leftSideButton;
#property (retain, nonatomic) IBOutlet UIButton *middleButton;
#property (retain, nonatomic) IBOutlet UIImageView *topImageView;
#property (nonatomic, assign) CommonViewController *parentObject;
#end
CommonViewController.m
#import "CommonViewController.h"
#interface CommonViewController ()
#end
#implementation CommonViewController
#synthesize topView, rightSideLabel, leftSideButton, middleButton, topImageView, parentObject;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
topView = [[UIView alloc] initWithFrame:CGRectMake(0, -416, 320, 460)];
topImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
topImageView.image = [UIImage imageNamed:#"top_bar_bg4.png"];
middleButton = [UIButton buttonWithType:UIButtonTypeCustom];
[middleButton setFrame:CGRectMake(120, topView.frame.size.height-44, 80, 44)];
[middleButton setBackgroundImage:[UIImage imageNamed:#"slide_arrow_open.png"] forState:UIControlStateNormal];
leftSideButton = [UIButton buttonWithType:UIButtonTypeCustom];
[leftSideButton setFrame:CGRectMake(0, topView.frame.size.height-44, 80, 44)];
[leftSideButton setTitle:#"BACK" forState:UIControlStateNormal];
[leftSideButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
rightSideLabel = [[UILabel alloc] initWithFrame:CGRectMake(200, topView.frame.size.height-40, 110, 40)];
rightSideLabel.text = #"PRODUCTS";
rightSideLabel.textColor = [UIColor whiteColor];
rightSideLabel.backgroundColor = [UIColor clearColor];
[topView addSubview:topImageView];
[topView addSubview:middleButton];
[topView addSubview:leftSideButton];
[topView addSubview:rightSideLabel];
[self.view addSubview:topView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
bViewController.h
#import <UIKit/UIKit.h>
#import "CommonViewController.h"
#interface bViewController : CommonViewController
#end
bViewController.m
#import "bViewController.h"
#interface bViewController ()
#end
#implementation bViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor lightGrayColor];
CommonViewController *newClass = [[CommonViewController alloc] init];
newClass.parentObject = self;
NSLog(#"text is %#", newClass.rightSideLabel.text);
newClass.rightSideLabel.text = #"NEW VALUE HERE";
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
What I want to do is keep common things in CommonViewController
Below is what I did...
In bViewController.m, I added below.
[[NSUserDefaults standardUserDefaults] setValue:#"New Value Here" forKey:#"notValue"];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName:#"ChangeRightSideLabel" object:self];
And in CommonViewController.m, viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receiveTestNotification:) name:#"ChangeRightSideLabel" object:nil];
- (void) receiveTestNotification:(NSNotification *) notification
{
// [notification name] should always be #"TestNotification"
// unless you use this method for observation of other notifications
// as well.
if ([[notification name] isEqualToString:#"ChangeRightSideLabel"]) {
NSLog (#"Successfully received the test notification!");
trightSideLabel = [[NSUserDefaults standardUserDefaults] valueForKey:#"notValue"];
rightSideLabel.text = trightSideLabel;
}
}
You have to respect MVC design Pattern approach. So instead of "newClass.rightSideLabel.text = #"NEW VALUE HERE";" You have to write :
in NewClass.h:
-#property(strong,nonatomic) stringText;
in NewClass.m:(ViewDidLoad Method)
-rightSideLabel.text=stringText;
in the current class:
-newClass.stringText= #"NEW Value HERE";
You need to make a string property for CommonViewController and assign the text to it.
And in CommonViewController's ViewDidLoad set that text to rightSideLabel.
This is firstPopoverViewController.h code:
#import <UIKit/UIKit.h>
#interface firstPopoverViewController : UIViewController
#end
This is my firstPopoverViewController.m code:
#import "firstPopoverViewController.h"
#interface firstPopoverViewController ()
#end
#implementation firstPopoverViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.contentSizeForViewInPopover = CGSizeMake(300, 290);
// Header label
UILabel *h1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 85)];
h1.font = [UIFont fontWithName:#"myFont" size:22.0];
h1.textColor = [UIColor blackColor];
h1.textAlignment = NSTextAlignmentCenter;
h1.text = #"Heading";
h1.numberOfLines = 0;
h1.backgroundColor = [UIColor greenColor];
// Ok button BG View
UIView *buttonBG = [[UIView alloc] initWithFrame:CGRectMake(0, 300-75, 300, 75)];
buttonBG.backgroundColor = [UIColor greenColor];
// Ok button
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(300/2-130/2, 290-35-15, 130, 35);
button.backgroundColor = [UIColor whiteColor];
[button setTitle:#"OK" forState:UIControlStateNormal];
[button addTarget:self action:#selector(closePop) forControlEvents:UIControlEventTouchUpInside];
button.adjustsImageWhenHighlighted=YES;
// Adding views
[self.view addSubview:h1];
[self.view addSubview:buttonBG];
[self.view addSubview:button];
}
-(void)closePop {
}
#end
Then there's ViewController.h:
#import <UIKit/UIKit.h>
#import "firstPopoverViewController.h"
#interface ViewController : UIViewController
#property (strong, nonatomic) UIButton *popButton;
#property (strong, nonatomic) firstPopoverViewController *firstPopoverViewController;
#property (strong, nonatomic) UIPopoverController *firstPopover;
#end
And finally ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
/* ##### UIPopController stuff ##### */
UIImage *popButtonImage = [UIImage imageNamed:#"menu.png"];
_popButton = [UIButton buttonWithType:UIButtonTypeCustom];
_popButton.frame = CGRectMake(0, 0, 73, 66);
[_popButton addTarget:self action:#selector(openPop) forControlEvents:UIControlEventTouchUpInside];
_popButton.adjustsImageWhenHighlighted=NO;
[_popButton setImage:popButtonImage forState:UIControlStateNormal];
[self.view addSubview:_popButton];
}
-(void)openPop {
if (_firstPopoverViewController == nil) {
//Create the _firstPopoverViewController.
_firstPopoverViewController = [[firstPopoverViewController alloc] init];
}
if (_firstPopover == nil) {
_firstPopover = [[UIPopoverController alloc] initWithContentViewController:_firstPopoverViewController];
_firstPopover.popoverContentSize = CGSizeMake(300, 290);
[_firstPopover presentPopoverFromRect:CGRectMake(0,0, 73, 66) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];
NSLog(#"show");
} else {
NSLog(#"dismiss");
[_firstPopover dismissPopoverAnimated:YES];
_firstPopover = nil;
}
}
#end
It's pretty basic code that displays a button and when I click this button it shows popover. I want to close this popover using button that's inside firstPopoverViewControll.m file. There's a closePop{} method, what should I put inside it to close this popover? Thanks.
By the way I'm beginner as you can see, I researched stackoverflow and there are some solutions with delegates, which seems to be working for others, but didn't work for me, could you please show me a solution on my code that I posted? Thank you people very much.
There may be a simpler method that I'm not aware of, but the following method should work:
Use NSNotificationCenter to post a notification back to the ViewController containing the UIPopOverController to tell it to dismiss the popover.
First, in ViewController.m viewDidLoad add:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(closePop:) name:#"ClosePopOver" object:nil];
Then add the following method to ViewController.m:
- (void)closePop:(NSNotification *)notification {
[_firstPopover dismissPopoverAnimated:YES];
}
Then in irstPopoverViewController.m:
- (void)closePop {
[[NSNotificationCenter defaultCenter] postNotificationName:#"ClosePopOver" object:nil];
}
That should do the trick.
A delegate is the way to go. I do admit though that I was confused by them at first, but they are quite simple to setup.
In your firstPopoverController.h put this:
#import <UIKit/UIKit.h>
#protocol FirstPopoverDelegate
- (void) closedPopover;
#end
#interface firstPopoverViewController : UIViewController
#property (nonatomic, assign) id< FirstPopoverDelegate > delegate;
#end
Then in your .m of you popover,
-(void)closePop
{
[self.delegate closedPopover];
}
In your main UIViewController's .h:
#import <UIKit/UIKit.h>
#import "firstPopoverViewController.h"
#interface ViewController : UIViewController <FirstPopoverDelegate>
#property (strong, nonatomic) UIButton *popButton;
#property (strong, nonatomic) firstPopoverViewController *firstPopoverViewController;
#property (strong, nonatomic) UIPopoverController *firstPopover;
#end
Then in the .m, first register to listen of the delegate by adding this to your openPop method:
this is important and easy to forget.. nothing will happen if it is not set
_firstPopoverViewController.delegate = self;
Finally, in your .m add the delegate method:
- (void)closedPopover
{
//you can also pass data back in this function, just modify its parameters here and when you define it in the .h of the popover
[_firstPopoverViewController dismissPopoverAnimated:YES];
}