- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要从一个 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)来实现其他功能。
因此,以下几点可以从这里拿走:
MySettingsDelegate
而不是 ViewControllerDelegate
。mySettings
重命名为 MySettingsViewController
。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/
我看了很多文章,但我仍然不清楚我们通常创建的普通委托(delegate)和多播委托(delegate)之间的区别。 public delegate void MyMethodHandler(objec
考虑以下几点: Action a1 = new Action(_insert); Action a2 = new Action(a1); a2 指的是什么?它是 a1,a1 的浅拷贝还是 a1 的深拷
我希望这听起来像是一个显而易见的问题,但是委托(delegate)返回类型是否也必须与其委托(delegate)的方法的返回类型相匹配? EG,像这样: public static void Save
我想使用 Kotlin 委托(delegate),但我不想在委托(delegate)人之外创建委托(delegate)。委托(delegate)的所有示例都如下所示: interface Worker
class SuperClass { var delegate : SuperClassDelegate? } protocol SuperClassDelegate { func d
我有一个加载 View 的 View ,需要将 View 推送到主导航 Controller 。 我已经为每个 View 设置了一个委托(delegate),并且基本上使我的调用沿着“链”返回到主导航
为简单起见,假设我想创建一个自定义 UITextField 并向其添加一个简单的行为;也就是说,如果文本字段成为第一响应者,背景颜色将变为绿色。 为此,在我的自定义类中,我必须将该类设置为委托(del
我非常有信心我应该能够使用非静态方法的委托(delegate),但下面给了我一个错误: public class TestClass { private delegate void TestD
在 C# 中不能从 System.Delegate 或 System.MulticastDelegate 继承。只要您声明标准的“运行时托管”方法,就完全可以在 MSIL 中执行此操作。但是,每次我向
我在 Storyboard 中定义了一个 iPad 界面,带有一个 SplitViewController。我想将 SplitViewController 的委托(delegate)设置为指向详细 C
我有几个解析器。有一个顶级的可以委托(delegate)给另一个。 Parser我们从 Reader 中获取他们的输入(可变)。我只想要一个 Parser为了能够一次解析,只有一个解析器应该有 Rea
一直以来我都在阅读关于反射的文章,每个人都在说:“反射很慢”,“反射很慢”。 现在我决定测试速度有多慢,令我惊讶的是,使用反射创建的委托(delegate)实际上是使用 lambda 创建的委托(de
在 Xcode 4.5 中启动了 Cocos2D 2.1 模板(没有物理引擎),针对 iOS 6 和 iPad。在 CDAudioManager.m 文件中,以下代码... AVAudioSessio
以下是来自未管理的 dll 的函数代码。它接受一个函数指针作为参数,并简单地返回被调用函数返回的值。 extern __declspec(dllexport) int _stdcall callDe
//NewCharts.h #import @interface NewCharts : UIViewController @property(nonatomic,retain)IBOutlet U
鉴于以下 MSDN 示例代码,为什么我不能定义 Action 委托(delegate)“内联”: public static void Main(string[] args) { Action
在虚幻引擎中,UFUNCTION用于通过附加说明符来丰富功能,以用于蓝图使用、复制和委托(delegate)。 然而,一些委托(delegate)类型似乎不允许绑定(bind) UFUNCTION(如
我刚刚将照片选择器放入我的项目中,一切正常。唯一的事情是它坚持在我设置委托(delegate)的地方给我以下警告 - Assigning to 'id' from incompatible type
我有一个 UIImageView 的子类,并且想将 self 作为参数传递给委托(delegate)。我在 MyImageView 之前收到错误“预期 ')'”。我需要将对象传递给委托(delegat
我正在开发 iOS 10 的语音转文本功能。 我希望调用 SFSpeechRecognitionTaskDelegate 的委托(delegate)方法来检查完成的结果。 func speechRec
我是一名优秀的程序员,十分优秀!