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.
Related
I have a UITextField and UILabel. When user entered some text to textField and tap "Enter" on keyboard I want to save text to the label then clear textField and make it first responder again. But something is going wrong. becomeFirstResponder does not work.
Here is the code of ViewController:
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UITextField *textField;
#property (weak, nonatomic) IBOutlet UILabel *label;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.textField addTarget:self action:#selector(saveResult:)
forControlEvents:UIControlEventEditingDidEndOnExit];
}
-(void) saveResult: (id) sender {
self.label.text = self.textField.text;
self.textField.text = #"";
[self.textField becomeFirstResponder];
}
#end
Here you go, this is a working sample, the "setFrame" methods were just made up out of the blue and you can change it up or just use the delegate methods that do all of this for you, pop this into your code, load up an iphone 6+ simulator, choose to show the hardware keyboard and this will work. There's no reason to add touch event handlers to your UITextField since the delegate methods provided by Apple do all the work for you.
#interface NSHHomeViewController () <UITextFieldDelegate>
#end
#property (weak, nonatomic) IBOutlet UITextField *textField;
#property (weak, nonatomic) IBOutlet UILabel *label;
#end
#implementation ViewController
{
UITextField * _passwordField;
UILabel * hid;
}
- (void)viewDidLoad {
[super viewDidLoad];
hid = [UILabel new];
[hid setFrame:CGRectMake(80, 200, 300, 60)];
[hid setFont:fontMagicForBoldNavigationBarNSHFont];
[hid setBackgroundColor:[UIColor babyBlue]];
[hid setTextColor:[UIColor blackBean]];
[self.view addSubview:hid];
_passwordField = [[UITextField alloc] init];
[_passwordField setSecureTextEntry:TRUE];
[_passwordField setPlaceholder:#"Password"];
[_passwordField setReturnKeyType:UIReturnKeyGo];
[_passwordField setTextAlignment:NSTextAlignmentLeft];
[_passwordField setDelegate:self];
[_passwordField setFont:fontMagicForRegularNSHFont];
[_passwordField setEnablesReturnKeyAutomatically:true];
[_passwordField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
[_passwordField setFrame:CGRectMake(30, SCREEN_HEIGHT/2, SCREEN_WIDTH-60, 55)];
UIView *spacerView4 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 15, 15)];
[_passwordField setLeftViewMode:UITextFieldViewModeAlways];
[_passwordField setLeftView:spacerView4];
[_passwordField setTextColor:[UIColor NSHBlueColor]];
[_passwordField setValue:fontMagicForRegularNSHFont forKeyPath:#"_placeholderLabel.font"];
[_passwordField setClearButtonMode:UITextFieldViewModeAlways];
[_passwordField setBackgroundColor:[UIColor colorWithWhite:1 alpha:1]];
[self.view addSubview:_passwordField];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == _passwordField) {
[hid setText:_passwordField.text];
[_passwordField setText:#""];
[_passwordField resignFirstResponder];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_passwordField becomeFirstResponder];
});
}
return TRUE;
}
This is just a working example, you need to declare your delegate correctly and declare the delegate of the UITextField correctly as you see above. Then choose which return key type you want for your button on the keyboard, you also then intercept these events by using the UITextFieldDelegate's "texFieldShouldReturn", you don't have to call a timed dispatch queue, but it put this in there for the effect of posting to the label, clearing the text, resigning the keyboard, and then after 1/2 a second, the keyboard becomes first responder again.
If you don't want target no longer. Remove the target in selector method, it works fine.
-(void) saveResult: (id) sender {
self.label.text = self.textField.text;
self.textField.text = #"";
[self.textField removeTarget:self action:nil forControlEvents:UIControlEventEditingDidEndOnExit];
[self.textField becomeFirstResponder];
}
Set Delegate and Datasource of UITextField in .h file and .m file and then try.
Hope it helps.
I'm making a test application in Xcode to learn objective-c, but when I click on the button in my app, it crashes.
My Viewcontroller.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController{
IBOutlet UILabel *myLabel;
UIButton *myButton;
UISwitch *mySwitch;
BOOL switched;
}
#property (nonatomic, retain)IBOutlet UILabel *myLabel;
#property (nonatomic, retain)IBOutlet UIButton *myButton;
#property (nonatomic, retain)IBOutlet UISwitch *mySwitch;
-(IBAction)buttonClick:(id)sender;
-(IBAction)switchMoved:(id)sender;
#end
My Viewcontroller.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize myButton;
#synthesize myLabel;
#synthesize mySwitch;
- (IBAction)buttonClick:(id)sender {
[myLabel setTextColor:[UIColor blueColor]];
sleep(1);
[myLabel setTextColor:[UIColor redColor]];
}
-(IBAction)switchMoved:(id)sender{
if(switched == TRUE){
[myLabel setTextColor:[UIColor blueColor]];
switched = FALSE;
}
else{
[myLabel setTextColor:[UIColor redColor]];
switched = TRUE;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[myLabel setText:#"This is a label"];
[myLabel setTextColor:[UIColor redColor]];
switched = TRUE;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The app crashes when I click the button in the simulator, but not when I switch the switch back and forth. Why is this happening? All of the outlets are connected correctly.
Instead of using sleep(1), which blocks the main thread and thus any UI-interaction/updates (as #Martin H also said in the comments), try to use performSelector:withObject:afterDelay: which will run the method given after a delay.
Here's an example:
- (IBAction)buttonClick:(id)sender {
[myLabel setTextColor:[UIColor blueColor]];
[self performSelector:#selector(changeTextColor:) withObject:nil afterDelay:2];
}
- (void)changeTextColor:(id)sender {
[myLabel setTextColor:[UIColor greenColor]];
}
// Edit: Oh… I'm posting this because I (as others) can't seem to find anything wrong with the code. Perhaps a wrong IB-binding. Perhaps you need to reset the the simulator.
I use GCD instead of perform selector but either should work. He's my implementation using GCD. You should never use sleep(); for UI changes. Either animation, perform selector, or GCD.
-(void)buttonClicked:(UIButton *)sender
{
[self setTextColor:[UIColor blueColor] forState:UIControlEventTouchUpInside];
dispatch_time_t waitTime = dispatch_time(DISPATCH_TIME_NOW,(int64_t)(1.0 * NSEC_PER_SEC));
dispatch_after(waitTime, dispatch_get_main_queue(), ^(void)
{
[self setTextColor:[UIColor redColor] forState:UIControlEventTouchUpInside]
});
}
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.
I have a Storyboard with a ViewController using a navigation controller and a TabBarController. I have been trying to resolve this for a few days now.
The problem:
Very often user I cannot interact with the view... that includes scrolling, tapping the text field and any buttons being pressed. Something is stopping me from interacting with the newly loaded UIView.
I have tried using the init method and tried using the init with frame method. The view is showing all the time though so maybe this is not the problem.
I have tried remaking the whole xib file, re-coding the .h and .m files and re-attaching all the outlets on the view.
I am stuck
In the view controller I am loading a UIView with separate .xib file and separate .h and .m file.
This is how I am doing it:
in my ViewController in the viewDidAppear method:
int startPos = self.navigationController.navigationBar.frame.size.height+20;
inviteFriendsView = [[InviteFriendsEmailAddressesView alloc] init];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"InviteFriendsEmailAddressesView" owner:self options:nil];
inviteFriendsView = (InviteFriendsEmailAddressesView*)[nib objectAtIndex:0];
[self.view addSubview:inviteFriendsView];
[inviteFriendsView setDelegate:self];
[inviteFriendsView setUserInteractionEnabled:YES];
[inviteFriendsView customizeView];
[inviteFriendsView setAlpha:0.0];
[inviteFriendsView setY:startPos];
IBAction method for showing the view:
- (IBAction)inviteFriendsButtonTapped:(id)sender {
[self.view bringSubviewToFront:inviteFriendsView];
[inviteFriendsView setUserInteractionEnabled:YES];
[inviteFriendsView animate];
}
Here is the .h and .m files which show how I am loading the view:
InviteFriendsEmailAddressesView.h
#import <UIKit/UIKit.h>
#import "InviteFriendsViewDelegate.h"
#import "InviteFriendsNetworkContollerDelegate.h"
#import "InviteFriendsNetworkController.h"
#interface InviteFriendsEmailAddressesView : UIView <UITextFieldDelegate, UITextViewDelegate, InviteFriendsNetworkContollerDelegate, UIGestureRecognizerDelegate>
- (void) customizeView;
- (void) animate;
#property BOOL visible;
#property int y;
#property id<InviteFriendsViewDelegate> delegate;
#property (strong, nonatomic) NSArray *emails;
#property int height;
#property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;
#property (weak, nonatomic) IBOutlet UILabel *inviteFriendsTitle;
#property (weak, nonatomic) IBOutlet UILabel *inviteFriendsDescription;
#property (weak, nonatomic) IBOutlet UITextField *userEmailTextField;
#property (weak, nonatomic) IBOutlet UIImageView *userEmailImageView;
#property (weak, nonatomic) IBOutlet UIButton *addFriendsButtonOutlet;
#property (weak, nonatomic) IBOutlet UILabel *emailAddressesDescription;
#property (weak, nonatomic) IBOutlet UIImageView *viewBackground;
#property (weak, nonatomic) IBOutlet UIView *emailAddressesCellBackground;
#property (weak, nonatomic) IBOutlet UILabel *emailAddressCellTextUILabel;
#property (weak, nonatomic) IBOutlet UIButton *emailAddressCancelButton;
#property (weak, nonatomic) IBOutlet UIView *emailAddressView;
#property (weak, nonatomic) IBOutlet UIButton *sendInviteButtonOutlet;
#property (weak, nonatomic) IBOutlet UIButton *progressSoFarButtonOutlet;
#property (weak, nonatomic) IBOutlet UIScrollView *viewScrollView;
#property (strong, nonatomic) InviteFriendsNetworkController *inviteFriendsNetworkController;
#pragma mark - UITextFieldDelegate Methods
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField; // return NO to disallow editing.
- (void)textFieldDidBeginEditing:(UITextField *)textField; // became first responder
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField; // return YES to allow editing to stop and to resign first responder status. NO to disallow the editing session to end
- (void)textFieldDidEndEditing:(UITextField *)textField; // may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; // return NO to not change text
- (BOOL)textFieldShouldClear:(UITextField *)textField; // called when clear button pressed. return NO to ignore (no notifications)
- (BOOL)textFieldShouldReturn:(UITextField *)textField; // called when 'return' key pressed. return NO to ignore.
#end
InviteFriendsEmailAddressesView.m
#import "InviteFriendsEmailAddressesView.h"
#import "UIFont+Theme.h"
#import "UIColor+Theme.h"
#import "UIImage+Theme.h"
#implementation InviteFriendsEmailAddressesView
#synthesize emails;
#synthesize visible;
#synthesize y;
#synthesize delegate;
#synthesize height;
#synthesize inviteFriendsNetworkController;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"InviteFriendsEmailAddressesView" owner:self options:nil];
self = [nib objectAtIndex:0];
}
return self;
}
- (id) init {
// self = [[[NSBundle mainBundle] loadNibNamed:#"InviteFriendsEmailAddressesView" owner:self options:nil] objectAtIndex:0];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(themeChanged)
name:#"New Theme Applied"
object:nil];
NSUserDefaults *properties = [NSUserDefaults standardUserDefaults];
if([properties objectForKey:#"emails"]){
emails = [properties objectForKey:#"emails"];
} else {
emails = [[NSArray alloc] init];
}
[self.viewScrollView setDelegate:self];
[self.activityIndicator setHidden:YES];
[self.viewScrollView setScrollEnabled:YES];
//CGRect newScrollViewFrame = self.viewScrollView.frame;
//newScrollViewFrame.origin.y = 0;
//newScrollViewFrame.size.height = keyWindowFrame.size.height;
//[self.viewScrollView setFrame:newScrollViewFrame];
// get the size of the screen and set the content size to the size of the screen plus the bottom bar.
CGRect screenRect = [[UIScreen mainScreen] bounds];
screenRect.size.height = screenRect.size.height-200;
[self.viewScrollView setContentSize:CGSizeMake(screenRect.size.width, 1200)];
[self.viewScrollView setFrame:screenRect];
[_viewScrollView setScrollEnabled:YES];
// 100 is the size of the tool bar.
[self updateEmailListView];
self.userEmailTextField.delegate = self;
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
[self.viewScrollView addGestureRecognizer:singleTap];
//reactionNetworkController
inviteFriendsNetworkController = [[InviteFriendsNetworkController alloc] init];
[inviteFriendsNetworkController setDelegate:self];
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
- (void) updateEmailListView {
// With some valid UIView *view:
for(UIView *subview in [self.emailAddressView subviews]) {
if([subview isHidden] == NO){
[subview removeFromSuperview];
}
}
// if we have email addresses in the email address list.
if([emails count] > 0){
// display and populate scrollview with email addresses.
for(int i =0; i < [emails count]; i++){
// every other view set it white so that it creates a grey, white, grey, white pattern.
if(i % 2 == 0){
[self.emailAddressesCellBackground setBackgroundColor:[UIColor whiteColor]];
} else {
[self.emailAddressesCellBackground setBackgroundColor:[UIColor grayColor]];
}
// generate our background
UIView *newBackground = [[UIView alloc] initWithFrame:CGRectMake(
self.emailAddressesCellBackground.frame.origin.x,
self.emailAddressesCellBackground.frame.origin.y+self.emailAddressesCellBackground.frame.size.height*i,
self.emailAddressesCellBackground.frame.size.width,
self.emailAddressesCellBackground.frame.size.height)];
[newBackground setTag:i];
// generate our email addresses label.
UILabel *newLabel = [[UILabel alloc] initWithFrame:CGRectMake(
self.emailAddressCellTextUILabel.frame.origin.x,
self.emailAddressCellTextUILabel.frame.origin.y+self.emailAddressesCellBackground.frame.size.height*i,
self.emailAddressCellTextUILabel.frame.size.width,
self.emailAddressCellTextUILabel.frame.size.height)];
[newLabel setTag:i];
[newLabel setText:[emails objectAtIndex:i]];
// generate the delete button and add a target for the selector when it is pressed.
UIButton *newButton = [[UIButton alloc] initWithFrame:CGRectMake(
self.emailAddressCancelButton.frame.origin.x,
self.emailAddressCancelButton.frame.origin.y+self.emailAddressCancelButton.frame.size.height*i,
self.emailAddressCancelButton.frame.size.width,
self.emailAddressCancelButton.frame.size.height)];
[newButton setTag:i];
[newButton addTarget:self action:#selector(deleteButtonPressed:) forControlEvents:UIControlEventTouchDown];
[newButton setImage:self.emailAddressCancelButton.imageView.image forState:UIControlStateNormal];
// attach the new views to the scrollview
[self.emailAddressView addSubview:newBackground];
[self.emailAddressView addSubview:newButton];
[self.emailAddressView addSubview:newLabel];
}
[self.emailAddressView setHidden:NO];
}
// if we do not have any emails added yet.
else {
[self.emailAddressView setHidden:YES];
}
}
- (void) deleteButtonPressed:(id)sender{
int tag = [sender tag];
NSLog(#"delete button pressed with sender tag: %i", [sender tag]);
NSMutableArray *mutableEmails = [emails mutableCopy];
[mutableEmails removeObjectAtIndex:tag];
emails = mutableEmails;
NSUserDefaults *properties = [NSUserDefaults standardUserDefaults];
[properties setObject:emails forKey:#"emails"];
[properties synchronize];
[self updateEmailListView];
}
- (void) customizeView{
[self.inviteFriendsTitle setFont:[UIFont themeFontNamed:#"viewTitleFont" ofSize:18]];
[self.viewBackground setImage:[UIImage themeImageNamed:#"backgroundImage"]];
[self.inviteFriendsDescription setFont:[UIFont themeFontNamed:#"normalTextFont" ofSize:13]];
[self.emailAddressesDescription setFont:[UIFont themeFontNamed:#"normalTextFont" ofSize:13]];
if(height == 0 &&[delegate respondsToSelector:#selector(getHeight)]){
height = [delegate getHeight];
[self setFrame:CGRectMake(0,
-height,
self.frame.size.width,
height)];
}
}
- (void) animate{
if(visible == YES){
[self slideOut];
visible = NO;
}
else{
[self customizeView];
[self slideIn];
visible = YES;
}
NSLog(#"is user interaction enabled in InviteFriendsView?: %hhd", self.isUserInteractionEnabled);
}
- (void) themeChanged {
[self customizeView];
}
- (void) slideIn {
NSLog(#"Slide in");
[[self superview] setUserInteractionEnabled:NO];
[self.activityIndicator setAlpha:1.0];
[self.activityIndicator startAnimating];
self.alpha = 1.0;
[UIView animateWithDuration:0.5
animations:^{
[self setFrame:CGRectMake(0,
y,
self.frame.size.width,
height)];
}
completion:^(BOOL finished) {
NSLog(#"DID finish slide in");
}];
}
- (void) slideOut{
NSLog(#"Slide out");
if([delegate respondsToSelector:#selector(getY)]){
y = [delegate getY];
}
[self setViewScrollView:self.viewScrollView];
[self setUserInteractionEnabled:YES];
[self.viewScrollView setUserInteractionEnabled:YES];
[self.viewScrollView setScrollEnabled:YES];
[self.viewScrollView setScrollsToTop:YES];
[UIView animateWithDuration:0.5
animations:^{
[self setFrame:CGRectMake(0,
-height+y,
self.frame.size.width,
height)];
}
completion:^(BOOL finished) {
self.alpha = 0.0;
[[self superview] setUserInteractionEnabled:YES];
}];
}
#pragma mark - UITextFieldDelegate Methods
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
return true;
}
// return NO to disallow editing.
- (void)textFieldDidBeginEditing:(UITextField *)textField{
}
// became first responder
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField{
return true;
}
// return YES to allow editing to stop and to resign first responder status. NO to disallow the editing session to end
- (void)textFieldDidEndEditing:(UITextField *)textField{
}
// may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
return true;
}
// return NO to not change text
- (BOOL)textFieldShouldClear:(UITextField *)textField{
return true;
}
// called when clear button pressed. return NO to ignore (no notifications)
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
[self addFriendToInviteButtonPressed:self];
[textField setText:#""];
return true;
}
// called when 'return' key pressed. return NO to ignore.
#pragma mark - Button Action Pressed Methods
- (IBAction)addFriendToInviteButtonPressed:(id)sender {
NSMutableArray *mutableEmails = [emails mutableCopy];
[mutableEmails addObject:self.userEmailTextField.text];
NSLog(#"mutableEmails: %#", mutableEmails);
NSUserDefaults *properties = [NSUserDefaults standardUserDefaults];
[properties setObject:mutableEmails forKey:#"emails"];
[properties synchronize];
emails = mutableEmails;
[self updateEmailListView];
[self.userEmailTextField setText:#""];
[self.userEmailTextField resignFirstResponder];
}
- (IBAction)sendInviteButtonPressed:(id)sender {
// send a POST request to the server with the emails.
NSString *stringEmails = [[emails valueForKey:#"description"] componentsJoinedByString:#""];
NSLog(#"stringEmails: %#", stringEmails);
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
int site = 0;
if([[defaults objectForKey:#"Theme"] isEqualToString:#"BOMG"]){
site = 1;
}
[self.inviteFriendsNetworkController inviteFriendsWithAddressList:emails AndSite:site];
}
- (IBAction)progressButtonPressed:(id)sender {
}
#pragma mark - InviteFriendsNetworkControllerDelegateMethods
- (void) didSendAddressList:(NSDictionary *)response{
}
- (void) failedTosendAddressList{
}
#pragma mark - UIGestureRecognizerDelegate methods
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
[self.userEmailTextField resignFirstResponder];
}
#end
This might be an issue with the frames, where the controls are rendered (partially) outside the superview frame. This can be caused by invalid autoresizing masks or autolayout constraints.
To debug this you can set 'clip subviews' to YES for the relavant controls. When you see some of the controls are not visible anymore (or just partially), check the frames and resizingmasks or constraints of the superview.
Check whether the view controller is added in the build phase compile source. If you not added the view controller in the compiler source (if its not added automatically) it will some effect in xib integration.
I found the answer. I had to comment out the line
[[self superview] setUserInteractionEnabled:NO];
inside slideIn(){..}
So disabling user interaction for the superview would of course stop all user interaction from happening in a subview (such as the scrollview).
Oh dear.
Thanks guys!
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