如何在多个视图中调用相同的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 
+1

您可以为每个视图使用不同的标记。用协议方法发送标签。我认为它会为你工作。 –

我使用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

有很多方法,你可以做到这一点。这里有两个:

  1. 添加sender参数,以此来-[ViewController isClicked]方法,并改变Mini因此调用-isClicked传递一个指针self。然后,-isClicked中的代码可以将它与它所知道的Mini的每个实例(即self.miniViewself.miniView2)进行比较,以查看它们中的任何一个是否是发送该消息的实例。

  2. 将属性添加到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); 
} 
+0

而不是添加另一个属性,我从属性检查器为每个视图设置标签。谢谢虽然.. –

+0

我只更新了答案,因为我认为在xib中标记每个视图并不是真正可扩展的。如果您在xib中标记视图,那意味着您在每个标记的代码中都有一个参考。请参阅我的附加答案。 – Amos