【问题标题】:Set Text of an UILabel after dismissViewController in other Class在其他类中关闭视图控制器后设置 UILabel 的文本
【发布时间】:2014-04-26 12:51:36
【问题描述】:

我还没有找到可以回答我的问题的类似问题。

我的问题是:为什么我不能在 dissmissViewController 之后从另一个类访问 UILabel?

这是我的代码:

ClassA.h:

@interface ClassA : UIViewController {
    UILabel *_ErrorLabel;
    UIActivityIndicatorView *_acIn1;
}

@property (weak, nonatomic) IBOutlet UILabel *ErrorLabel;
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *acIn1;

ClassA.m:

shouldPerformSegue, prepareForSegue and statusBarStyle Methods

ClassB.h:

- (IBAction)dismiss;

ClassB.m:

- (IBAction)dismiss
{
  [self dismissViewControllerAnimated:YES completion:^{
      ClassA *login = [[ClassA alloc] init];
      [[login ErrorLabel] setText:@"Please use login."];
      [[login acIn1] stopAnimating];
      [[login acIn1] setHidesWhenStopped:YES];
      [[login acIn1] setHidden:YES];
  }];
}

这是我的代码,我真的希望有人能帮助我:我即将放弃我不知道为什么这行不通!

感谢您的帮助。

~马库斯

编辑1:

我有一个 ViewController ClassA,它包含两个文本字段,当您单击登录时,您会进入一个 TabBarController,其中一个选项卡包含 ClassB ViewController,并且在 ClassB ViewController 中有一个注销按钮 --> 关闭,当您单击此按钮时按钮你应该来到 ClassA ViewController 并且 ErrorLabel 文本应该改变。

完整类:A --> LoginViewControler.h

#import <UIKit/UIKit.h>
#import "ShowProfileViewController.h"

@interface LoginViewController : UIViewController <ShowProfileViewControllerDelegate> {
    UILabel *_ErrorLabel;
    UIActivityIndicatorView *_acIn1;
}

@property (weak, nonatomic) IBOutlet UITextField *usernameTextField;
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;
@property (weak, nonatomic) IBOutlet UILabel *ErrorLabel;
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *acIn1;

@end

完整类:A --> LoginViewController.m

#import "LoginViewController.h"
#import "NewsNavigationController.h"
#import "TabViewController.h"

@interface LoginViewController () <UITextFieldDelegate>

@end

@implementation LoginViewController

@synthesize usernameTextField;
@synthesize passwordTextField;
@synthesize ErrorLabel;
@synthesize acIn1;

- (void)viewDidLoad
{
    [super viewDidLoad];
    [usernameTextField setDelegate:self];
    [passwordTextField setDelegate:self];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    
    if([identifier isEqualToString:@"login"])
    {
        [acIn1 startAnimating];
        [acIn1 setHidden:NO];
        if([self login]){
            return YES;
        } else {
            [self showErrorMessage:@"Data not correct!"];
            [acIn1 stopAnimating];
            [acIn1 setHidesWhenStopped:YES];
            [acIn1 setHidden:YES];
            return NO;
        }
    }
    else {
        [acIn1 stopAnimating];
        [acIn1 setHidesWhenStopped:YES];
        [acIn1 setHidden:YES];
        return NO;
    }
}

- (void)showErrorMessage:(NSString *)message
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error!"
                                                    message:message
                                                    delegate:self
                                                    cancelButtonTitle:@"OK"
                                                    otherButtonTitles:nil];
    [alert show];
}

- (BOOL)login
{
    NSString *usernameS = usernameTextField.text;
    NSString *passwordS = passwordTextField.text;
    
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:8888/login.php?username=%@&password=%@", usernameS, passwordS]]];
    
    NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

    NSDictionary *loginDic = [jsonDictionary objectForKey:@"login"];

    NSString *ErrorString = [loginDic objectForKey:@"returnString"];
    
    NSLog(@"[+] Login: %@", ErrorString);
    
    if ([ErrorString isEqualToString:@"Success"]){
        ErrorLabel.text = @"Login";
        return YES;
    }
    else {
        ErrorLabel.text = ErrorString;
        return NO;
    }
    
}

- (void)didDismissViewController
{
    [ErrorLabel setText:@"Bitte benutzen Sie den Login."];
    [acIn1 stopAnimating];
    [acIn1 setHidesWhenStopped:YES];
    [acIn1 setHidden:YES];
}

- (void)prepareForSegue:(UIStoryboardSegue *)inSegue sender:(id)inSender
{
    if([inSegue.identifier isEqualToString:@"login"])
    {
        ShowProfileViewController *vc = [[ShowProfileViewController alloc] init];
        vc.delegate = self;
        TabViewController *tabViewController = inSegue.destinationViewController;
        NewsNavigationController *theController = [[tabViewController viewControllers] objectAtIndex:0];
        [self presentViewController:vc animated:YES completion:nil];
    }
}


@end

完整类:B --> ShowProfileViewController.h

#import <UIKit/UIKit.h>

@protocol ShowProfileViewControllerDelegate

- (void)didDismissViewController;

@end

@interface ShowProfileViewController : UIViewController

@property (nonatomic, assign) id<ShowProfileViewControllerDelegate> delegate;

- (IBAction)dismiss;

@end

完整类:B --> ShowProfileViewController.m

#import "ShowProfileViewController.h"
#import "LoginViewController.h"

@interface ShowProfileViewController ()

@end

@implementation ShowProfileViewController


- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(BOOL) textFieldShouldReturn:(UITextField *)textField{
    
    [textField resignFirstResponder];
    return YES;
}

- (void)viewWillAppear:(BOOL)inAnimated
{
    [super viewWillAppear:inAnimated];
}

- (IBAction)dismiss
{
    [self dismissViewControllerAnimated:YES completion:^{
        [self.delegate didDismissViewController];
    }];
}

@end

【问题讨论】:

    标签: ios objective-c class


    【解决方案1】:

    这不起作用,因为在完成块中,您正在创建 LoginViewController 的新实例,并设置其文本。您实际上应该做的是设置现有LoginViewController 的文本,它应该在关闭ShowProfileViewController 后出现

    为了实现您想要的行为,您可以使用delegation pattern。如果你不熟悉这项技术,学习它是非常重要的。它在 iOS 和 Mac OS X 开发中被广泛使用。

    您可能需要对以下代码进行一些调整。

    ShowProfileViewController.h 中,在@interface 之前添加:

    @protocol ShowProfileViewControllerDelegate
    
    - (void)didDismissViewController    
    
    @end
    

    另外,将以下属性声明添加到ShowProfileViewController

    @property (nonatomic, assign) id<ShowProfileViewControllerDelegate> delegate;
    

    然后,更改 LoginViewController.h 的样子

    #import "ShowProfileViewController.h" 
    
    @interface LoginViewController : UIViewController <ShowProfileViewControllerDelegate> {
        UILabel *_ErrorLabel;
        UIActivityIndicatorView *_acIn1;
    }
    
    @property (weak, nonatomic) IBOutlet UILabel *ErrorLabel;
    @property (weak, nonatomic) IBOutlet UIActivityIndicatorView *acIn1;
    

    现在,在 ShowProfileViewController.m 中,替换 dismiss 方法中的代码,使其如下所示:

    - (IBAction)dismiss
    {
      [self dismissViewControllerAnimated:YES completion:^{
          [self.delegate didDismissViewController];
      }];
    }
    

    LoginViewController.m中,添加如下方法:

    - (void)didDismissViewController 
    {
      [[self ErrorLabel] setText:@"Please use login."];
      [[self acIn1] stopAnimating];
      [[self acIn1] setHidesWhenStopped:YES];
      [[self acIn1] setHidden:YES];
    }
    

    最后,您需要将ShowProfileViewController 中的delegate 属性设置为指向LoginViewController 实例。在LoginViewController.m 中查找您创建的代码部分并呈现ShowProfileViewController 视图控制器并将delegate 属性设置为self。如果您使用故事板,您应该在 prepareForSegue: 中使用。

    【讨论】:

    • 不知何故我不明白您的最后一句话:“最后,您需要在 ClassB 中设置委托属性以指向 ClassA 实例。在 ClassA.m 中查找您创建的代码部分并呈现 ClassB 视图控制器并将委托属性设置为 self。”你能给我举个例子吗?
    • 我在答案中添加了一个示例。
    • 在 prepareForSegue 方法中设置委托是个好主意吗?
    • 是的,可以的。
    • 警告:尝试在 上显示 ,其视图不在窗口层次结构中!
    【解决方案2】:
      ClassA *login = [[ClassA alloc] init];
    

    正在创建一个全新的实例。不是你用来上 B 班的那个

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 2023-03-15
      • 2016-03-10
      相关资源
      最近更新 更多