我有一个使用导航控制器和 TabBarController 的带有 ViewController 的故事板。这几天我一直在尝试解决这个问题。
问题:
很多时候,用户我无法与视图交互...包括滚动、点击文本字段和按下任何按钮。有些东西阻止我与新加载的 UIView 交互。
我尝试过使用 init 方法并尝试使用 init with frame 方法。视图一直在显示,所以也许这不是问题。
我尝试重新制作整个 xib 文件,重新编码 .h 和 .m 文件并重新附加视图上的所有插座。
我被困住了
在视图控制器中,我正在加载一个带有单独 .xib 文件和单独 .h 和 .m 文件的 UIView。
这就是我的做法:
在我的 ViewController 中的 viewDidAppear 方法中:
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 方法:
- (IBAction)inviteFriendsButtonTapped:(id)sender {
[self.view bringSubviewToFront:inviteFriendsView];
[inviteFriendsView setUserInteractionEnabled:YES];
[inviteFriendsView animate];
}
这是显示我如何加载视图的 .h 和 .m 文件:
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