.xib文件关于ViewController的init UIView用户交互无法正常工作

时间:2013-11-14 11:23:05

标签: ios objective-c xcode storyboard xib

我有一个带有ViewController的Storyboard,它使用导航控制器和TabBarController。我一直试图解决这个问题几天了。

问题:

用户经常无法与视图交互...包括滚动,点击文本字段和按下的任何按钮。有些东西阻止我与新装的UIView交互。

我尝试过使用init方法并尝试使用init with frame方法。视图一直在显示,所以也许这不是问题。

我尝试重新编写整个xib文件,重新编码.h和.m文件并重新连接视图上的所有插座。

我被困了

在视图控制器中,我正在使用单独的.xib文件和单独的.h和.m文件加载UIView。

我就是这样做的:

在ViewDidAppear方法的ViewController中

   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

3 个答案:

答案 0 :(得分:2)

这可能是帧的问题,其中控件(部分地)在超视图帧之外呈现。这可能是由无效的自动调整遮罩或自动布局约束引起的。

要对此进行调试,您可以将“剪辑子视图”设置为“是”以进行相关控件。当您看到某些控件不再可见(或仅部分显示)时,请检查帧和调整大小以及超级视图的约束。

答案 1 :(得分:0)

检查是否在构建阶段编译源中添加了视图控制器。如果未在编译器源中添加视图控制器(如果未自动添加),则会对xib集成产生一些影响。

答案 2 :(得分:0)

我找到了答案。我不得不注释掉这一行

[[self superview]  setUserInteractionEnabled:NO];

在slideIn(){..}

因此,禁用超级视图的用户交互当然会阻止所有用户交互在子视图中发生(例如scrollview)。

哦,亲爱的。

谢谢你们!