gpt4 book ai didi

ios - 无法让委托(delegate)在我的观点之间工作

转载 作者:行者123 更新时间:2023-11-28 21:40:14 24 4
gpt4 key购买 nike

我需要从一个 View 调用一些方法到另一个 View ,但我似乎无法让它工作。我做错了什么?

这是我的ViewController.h

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

@protocol ViewControllerDelegate <NSObject>
@required
- (void) getDefaults;
- (void) updateSubTotal: ( float ) value;
@end

@interface ViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate> {
id <ViewControllerDelegate> delegate;
}

@property (retain) id delegate;
.
. (other declarations)
.
@end

ViewController.m

#import "ViewController.h"
#import "mySettings.h"

@interface ViewController ( )
@property (assign) mySettings *settingsVC;
@end

@implementation ViewController

- ( void ) viewDidLoad {
[ super viewDidLoad ] ;
// Do any additional setup after loading the view, typically from a nib.

self.userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.Just-The-Tip"] ;
[ self getDefaults ] ;

self.arrPercent = @ [ @"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",@"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34",@"35",@"36",@"37",@"38",@"39",@"40",@"41",@"42",@"43",@"44",@"45",@"46",@"47",@"48",@"49",@"50" ] ;
self.arrPeople = @ [ @"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20" ] ;

self.myPicker.dataSource = self;
self.myPicker.delegate = self;

if ( self.bRememberLastBill )
{
self.subtotal = [ self.userDefaults floatForKey:@"sub_total" ] ;
self.strSubTotal = [ NSString stringWithFormat: @"%.2f", self.subtotal ] ;
[ self updateSubTotal:-3 ] ;
}

// BEGIN ENABLE DONE BUTTON FOR NUMPAD
UIToolbar * keyboardDoneButtonView = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 32)];;
keyboardDoneButtonView.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc] initWithTitle:@"Clear" style:UIBarButtonItemStyleDone target:self action:@selector(clearClicked:)],
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(doneClicked:)], nil
];
[keyboardDoneButtonView sizeToFit];
self.field_SubTotal.inputAccessoryView = keyboardDoneButtonView;
// END ENABLE DONE BUTTON FOR NUMPAD

UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 16, 60)];
self.field_SubTotal.rightView = paddingView;
self.field_SubTotal.rightViewMode = UITextFieldViewModeAlways;

self.settingsVC = [[mySettings alloc] init];
self.settingsVC.delegate = self ;

[ self animate ] ;
}

- ( void ) getDefaults
{
// lots of stuff here
}

- ( void ) updateSubTotal: ( float ) value
{
// even more code here
}

mySettings.h

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

@interface mySettings : UIViewController {

}

@property (nonatomic, assign) id delegate;
.
. (a bunch of declarations)
.
@end

我的设置.m

#import "mySettings.h"
#import "ViewController.h"

@interface mySettings ( )

@end

@implementation mySettings

@synthesize delegate;

- ( void ) viewDidLoad {
[ super viewDidLoad ] ;
// Do any additional setup after loading the view.

//self.userDefaults = [ NSUserDefaults standardUserDefaults ] ;
self.userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.Just-The-Tip"] ;

[ self getDefaults ] ;

self.textDefaultTax.text = [ NSString stringWithFormat:@"%.3f", self.default_tax ] ;
self.textDefaultTip.text = [ NSString stringWithFormat:@"%.f", self.default_tip ] ;

// BEGIN ENABLE DONE BUTTON FOR NUMPAD
UIToolbar * keyboardDoneButtonView = [[UIToolbar alloc] init];
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(doneClicked:)],
nil]];
[keyboardDoneButtonView sizeToFit];
self.textDefaultTip.inputAccessoryView = keyboardDoneButtonView;
self.textDefaultTax.inputAccessoryView = keyboardDoneButtonView;
// END ENABLE DONE BUTTON FOR NUMPAD

[ self animate ] ;
}

// a few methods later

- (IBAction)up_default_exclude_tax:(id)sender {
self.bExcludeTax = self.switchExcludeTax.isOn;
[ self setDefaults ] ;
[ self.delegate getDefaults ];
[ self.delegate updateSubTotal:-3 ];
}

最佳答案

坦率地说,你几乎把我弄糊涂了:)。您实现委托(delegate)设计模式和连接 View Controller 的方式不是建议/记录的方式。

让我们一步步来。

第 1 步:MySettings(如 UITableViewController)实现一些功能并依赖其委托(delegate)来实现其他功能。

因此,以下几点可以从这里拿走:

  1. 协议(protocol)定义必须是 MySettingsDelegate 而不是 ViewControllerDelegate
  2. mySettings 重命名为 MySettingsViewController
  3. MySettingsViewController 不应导入 ViewController。它必须使用其 delegate 属性与 ViewController 进行交互。

这就是我的 MySettingsViewController 发布这些更改后的样子。

MySettingsViewController.h

`

@protocol MySettingsViewControllerDelegate <NSObject>
@required
- (void) getDefaults;
- (void) updateSubTotal: ( float ) value;
@end




@interface MySettingsViewController : UIViewController {

}

@property (nonatomic, assign) id delegate;
.
. (a bunch of declarations)
.
@end`

第 2 步:您不再需要对属性调用 @synthesis。此外,在委托(delegate)上调用方法之前,最好先进行 nil 检查。请查看我的 MySettingsViewController.m 的外观。我还添加了一些 NSLog 语句供您验证控件是否出现。

MySettingsViewController.m

@implementation MySettingsViewController
- ( void ) viewDidLoad {
[ super viewDidLoad ] ;
// Do any additional setup after loading the view.

//self.userDefaults = [ NSUserDefaults standardUserDefaults ] ;
self.userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.Just-The-Tip"] ;

[ self getDefaults ] ;

self.textDefaultTax.text = [ NSString stringWithFormat:@"%.3f", self.default_tax ] ;
self.textDefaultTip.text = [ NSString stringWithFormat:@"%.f", self.default_tip ] ;

// BEGIN ENABLE DONE BUTTON FOR NUMPAD
UIToolbar * keyboardDoneButtonView = [[UIToolbar alloc] init];
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(doneClicked:)],
nil]];
[keyboardDoneButtonView sizeToFit];
self.textDefaultTip.inputAccessoryView = keyboardDoneButtonView;
self.textDefaultTax.inputAccessoryView = keyboardDoneButtonView;
// END ENABLE DONE BUTTON FOR NUMPAD

[ self animate ] ;
}

// a few methods later

- (IBAction)up_default_exclude_tax:(id)sender {
self.bExcludeTax = self.switchExcludeTax.isOn;
[self setDefaults];

NSLog(@"Action taken");

if (self.delegate && [self.delegate respondsToSelector:@selector(getDefaults)]) {
NSLog(@"Calling getDefaults");
[self.delegate getDefaults];
}

if (self.delegate && [self.delegate respondsToSelector:@selector(updateSubTotal:)]) {
NSLog(@"Calling updateSubTotal:");
[self.delegate updateSubTotal:-3];
}
}

第 3 步:现在,我的支持类已准备就绪,可以使用它了。是时候编写 ViewController 类了。不确定为什么还要在 ViewController 的 header 中添加委托(delegate),我们实际上不需要它。这就是我的 ViewController.h 的样子:

ViewController.h

@interface ViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate, MySettingsViewControllerDelegate> {

}

.
. (other declarations)
.
@end

第 4 步:现在是主要部分。请确保您持有对 MySettingsViewController 的强引用。这就是我的 ViewController.m 的样子:

ViewController.m

@interface ViewController()
@property (nonatomic, strong) MySettingsViewController *settingsVC;
@end
- ( void ) viewDidLoad {
[super viewDidLoad ] ;
// Do any additional setup after loading the view, typically from a nib.

self.userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.Just-The-Tip"] ;
[ self getDefaults ] ;

self.arrPercent = @ [ @"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",@"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34",@"35",@"36",@"37",@"38",@"39",@"40",@"41",@"42",@"43",@"44",@"45",@"46",@"47",@"48",@"49",@"50" ] ;
self.arrPeople = @ [ @"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20" ] ;

self.myPicker.dataSource = self;
self.myPicker.delegate = self;

if ( self.bRememberLastBill )
{
self.subtotal = [ self.userDefaults floatForKey:@"sub_total" ] ;
self.strSubTotal = [ NSString stringWithFormat: @"%.2f", self.subtotal ] ;
[ self updateSubTotal:-3 ] ;
}

// BEGIN ENABLE DONE BUTTON FOR NUMPAD
UIToolbar * keyboardDoneButtonView = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 32)];;
keyboardDoneButtonView.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc] initWithTitle:@"Clear" style:UIBarButtonItemStyleDone target:self action:@selector(clearClicked:)],
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(doneClicked:)], nil
];
[keyboardDoneButtonView sizeToFit];
self.field_SubTotal.inputAccessoryView = keyboardDoneButtonView;
// END ENABLE DONE BUTTON FOR NUMPAD

UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 16, 60)];
self.field_SubTotal.rightView = paddingView;
self.field_SubTotal.rightViewMode = UITextFieldViewModeAlways;

self.settingsVC = [[MySettingsViewController alloc] init];
self.settingsVC.delegate = self ;

[ self animate ] ;
}

- ( void ) getDefaults
{
// lots of stuff here
}

- ( void ) updateSubTotal: ( float ) value
{
// even more code here
}

我相信这一定能解决您的问题,并使委托(delegate)模式更加清晰。您还需要确保当 MySettingsViewController 处于事件状态并调用其委托(delegate)时,ViewController 也保留在内存中。

编辑:如果您使用的是 Storyboard

请确保您在正确的对象上正确设置委托(delegate)。不要实例化您自己的对象。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"SegueRegistrationUserAction"]) {
[(MySettingsViewController *)segue.destinationViewController setDelegate:self];
}
}

最终编辑(在代码中修复):

所以,我查看了您的代码并发现了问题所在。这显然是不同的对象问题。您正在使用 Storyboard,并且还在代码中创建了一个 mySettings 对象。当您通过 Storyboard连接时,您应该使用从 Storyboard创建的对象并避免创建您自己的对象。当我更改您的 ViewController.m 中的以下方法时,它解决了问题。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
self.settingsVC = (mySettings *)segue.destinationViewController;
self.settingsVC.delegate = self;
}

关于ios - 无法让委托(delegate)在我的观点之间工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32467416/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com