如何在多个视图中调用相同的xib,但区分哪些是我正在进行交互?
我想在我的viewcontroller上多次使用一个xib文件(这只是一个简单的视图)。我可以将它添加到我的viewcontroller不止一次,并与它们进行交互。问题是,我如何区分这些视图来知道我点击哪一个?如何在多个视图中调用相同的xib,但区分哪些是我正在进行交互?
例如,当我在我的firstView挖掘,我想打印“苹果”当我在第二视图点击i湾打印“橘子”
下面你可以看到我的代码,这里是GitHub库https://github.com/TimurAykutYildirim/demoView/tree/multiple-instance
ViewController.h
#import <UIKit/UIKit.h>
#import "Mini.h"
@interface ViewController : UIViewController <SelectionProtocol>
@property (weak, nonatomic) IBOutlet Mini *miniView;
@property (weak, nonatomic) IBOutlet Mini *miniView2;
@end
ViewController.m
0:为你我的代码玩#import "ViewController.h"
@interface ViewController()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.miniView.delegate = self;
self.miniView2.delegate = self;
}
-(void) isClicked {
NSLog(@"apples");
NSString * storyboardName = @"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
[self presentViewController:vc animated:YES completion:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
Mini.h
#import <UIKit/UIKit.h>
@protocol SelectionProtocol;
@interface Mini : UIView
@property (nonatomic, weak) id<SelectionProtocol> delegate;
- (IBAction)btnClick:(id)sender;
@end
@protocol SelectionProtocol <NSObject>
@required
-(void) isClicked;
@end
Mini.m
#import "Mini.h"
@implementation Mini
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[self load];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self load];
}
return self;
}
- (void)load {
UIView *view = [[[NSBundle bundleForClass:[self class]] loadNibNamed:@"Mini" owner:self options:nil] firstObject];
[self addSubview:view];
view.frame = self.bounds;
}
- (IBAction)btnClick:(id)sender {
if ([self.delegate conformsToProtocol:@protocol(SelectionProtocol)]) {
[self.delegate isClicked];
}
}
@end
我使用ENUM
用于视图类型之间进行区分。
typedef NS_ENUM(NSUInteger, <#MyViewType#>) {
<#MyViewTypeDefault#>,
<#MyViewTypeA#>,
<#MyViewTypeB#>,
};
@property (nonatomic, assign) MyEnum viewType;
协议:
-(void) isClickedForViewType:(MyEnum)viewType;
调用委托方法常用的方法是包括呼叫者作为PARAM。你的情况应该是这样的:
- (IBAction)btnClick:(id)sender {
if ([self.delegate conformsToProtocol:@protocol(SelectionProtocol)]) {
[self.delegate isClickedOnMiniView:self];
}
}
基本上,这个公约是为了掩盖这样的情况 - 一个对象是很多类似的人的代表。
检查苹果的文档在本公约的例子: https://developer.apple.com/documentation/uikit/uitableviewdelegate
有很多方法,你可以做到这一点。这里有两个:
添加
sender
参数,以此来-[ViewController isClicked]
方法,并改变Mini
因此调用-isClicked
传递一个指针self
。然后,-isClicked
中的代码可以将它与它所知道的Mini
的每个实例(即self.miniView
和self.miniView2
)进行比较,以查看它们中的任何一个是否是发送该消息的实例。将属性添加到
Mini
可让您区分两者,例如name
。您可以在-viewDidLoad
中配置该属性,如self.miniView.name = @"apples"
,或者甚至可以使用“用户定义的运行时属性”在.xib文件中执行该属性。“然后你就可以有Mini
通是name
财产作为参数传递给那些需要知道的Mini
实例调用者的方法。(您也可以结合1 & 2,并传递给self
的引用,以便ViewController
可以检查name
参数或任何别的就是了。)
我从你的问题是某处Mini
厦门国际银行有文本“苹果”(或特定的厦门国际银行取水果)出口假设。
在在这种情况下,您可以将协议更改为:
- (void)isClickedFromView:(Mini *)mini
在委托(ViewController.m)改变btnClick
行动:
- (IBAction)btnClick:(id)sender {
if ([self.delegate conformsToProtocol:@protocol(SelectionProtocol)]) {
[self.delegate isClickedFromView:self];
}
}
像fruitLabel
出口添加到您的Mini
类。
@property (weak, nonatomic) IBOutlet UILabel *fruitLabel
现在,当代表得到呼叫时,可以拨打:对于如果数据(在这种情况下fruits
)在代码中
NSLog(@"Fruit: %@", mini.fruitLabel.text);
=====附加应答=== ==
如果您已经以编程方式获得了数据(如水果数组),那么将Mini类以相同方式排列在数组中可能更容易。
所以,如果miniViewArray
包含您Mini
类,数组 和fruitArray
含有水果的NSString的数组,你可以这样做:
在您设定的MiniView中的委托时,你可以将它们添加到阵列..是这样的:
NSArray *fruitArray = @[ @"apples", @"oranges" ];
NSArray *miniViewArray = @[ miniView, miniView2 ];
然后在委托调用你可以做(使用相同的协议更改如上):
- (void)isClickedFromView:(Mini *)mini {
NSInteger fruitIndex = [miniViewArray indexOfObject:mini];
NSString fruitName = fruitArray[fruitIndex];
NSLog(@"Fruit: %@", fruitName);
}
而不是添加另一个属性,我从属性检查器为每个视图设置标签。谢谢虽然.. –
我只更新了答案,因为我认为在xib中标记每个视图并不是真正可扩展的。如果您在xib中标记视图,那意味着您在每个标记的代码中都有一个参考。请参阅我的附加答案。 – Amos
您可以为每个视图使用不同的标记。用协议方法发送标签。我认为它会为你工作。 –