【问题标题】:Get array of all UITextFields获取所有 UITextFields 的数组
【发布时间】:2012-01-13 21:58:25
【问题描述】:

如何在视图控制器中获取所有 UITextField 的数组?

编辑:我不想将文本字段硬编码到数组中。我实际上想从该委托的调用者那里获取委托中所有字段的列表。

【问题讨论】:

标签: iphone objective-c ios5


【解决方案1】:

搜索所有子视图的子视图的递归实现:(这样您可以捕获嵌入在 uiscrollview 等中的文本字段)

-(NSArray*)findAllTextFieldsInView:(UIView*)view{
    NSMutableArray* textfieldarray = [[[NSMutableArray alloc] init] autorelease];
    for(id x in [view subviews]){
        if([x isKindOfClass:[UITextField class]])
            [textfieldarray addObject:x];

        if([x respondsToSelector:@selector(subviews)]){
            // if it has subviews, loop through those, too
            [textfieldarray addObjectsFromArray:[self findAllTextFieldsInView:x]];
        }
    }
    return textfieldarray;
}

-(void)myMethod{
   NSArray* allTextFields = [self findAllTextFieldsInView:[self view]];
   // ...
 }

【讨论】:

  • 这不是if([x respondsToSelector:@selector(subviews)]){ 多余的-subviews 返回@property(nonatomic, readonly, copy) NSArray *subviews。因此,该数组中的任何项目都是UIView 类型或子类或UIView,它响应@selector(subviews)
  • 我对向我什至不知道该类的对象抛出消息感到非常不安 - 如果某些傻瓜子类 UIView 以这样一种方式 subviews 包含非@ 987654330@-inherited 对象,因此对象不响应 @selector(subviews)?
  • 重写该方法并添加非 UIView 并没有真正意义 - 如果用户这样做,他们很可能足够聪明,知道他们为什么这样做以及任何风险它可能涉及。至少这是人们希望的;)
  • @jostster 此解决方案不需要您对数组进行硬编码。通过 addSubview 或 Interface Builder 添加到视图的任何 UITextField 都会自动具有 subviews 数组。
  • @Tim 我正在使用您的代码并进行了一些更改。基本上我把 findAllTextFieldsInView 放在我的 TextFieldDelegate 类中,并在我的视图中调用它。我需要在 TextFieldDelegate 中设置一个从视图到控制器的变量,因此当委托调用 findAllTextFieldsInView 时,它将解析控制器。我怎样才能做到这一点?我的控制器可以是 UIViewController 或 UITableViewController。
【解决方案2】:

如果您知道您需要一个包含所有 UITextFieldNSArray,那么为什么不将它们添加到数组中呢?

NSMutableArray *textFields = [[NSMutableArray alloc] init];

UITextField *textField = [[UITextField alloc] initWithFrame:myFrame];

[textFields addObject:textField]; // <- repeat for each UITextField

如果您使用的是笔尖,请使用IBOutletCollection

@property (nonatomic, retain) IBOutletCollection(UITextField) NSArray *textFields;

然后将所有UITextField 连接到该数组

【讨论】:

  • 将它们硬编码成一个数组是没有意义的......违背了我想要获得所有文本字段的数组的目的,因为我可以手动创建它......
  • 如果在创建 UITextField 时将它们添加到 NSMutableArray,则没有硬编码
  • 我将根据来自 API 的数据创建文本字段,因此我不知道那里有哪些文本字段。我可以在创建它们时以编程方式添加它们,但我更愿意只获取已经存在的字段列表,而不是依赖开发人员将每个字段添加到数组中。
  • 为什么要添加它们,然后在第二遍中找到它们?这听起来非常低效。如果您想引用UITextField,请在创建它时将其添加到数组中(并且已经有了引用)。
【解决方案3】:

-使用以下代码获取包含视图上呈现的所有 UITextField 的文本值的数组:

   NSMutableArray *addressArray=[[NSMutableArray alloc] init];

   for(id aSubView in [self.view subviews])
   {
           if([aSubView isKindOfClass:[UITextField class]])
           {
                  UITextField *textField=(UITextField*)aSubView;
                  [addressArray addObject:textField.text];
           }
   }
   NSLog(@"%@", addressArray);

【讨论】:

    【解决方案4】:
    extension UIView 
    {
       class func getAllSubviewsOfType<T: UIView>(view: UIView) -> [T] 
       {
           return view.subviews.flatMap { subView -> [T] in
           var result = UIView.getAllSubviewsOfType(view: subView) as [T]
           if let view = subView as? T {
               result.append(view)
           }
           return result
         }
       }
    
       func getAllSubviewsWithType<T: UIView>() -> [T] {
           return UIView.getAllSubviewsOfType(view: self.view) as [T]
       }
    }
    

    如何使用文本字段:

    let textFields = self.view.getAllSubviewsWithType() as [UITextField]
    

    【讨论】:

      【解决方案5】:

      您可以循环浏览控制器视图的子视图。

      这是一个粗略示例:

      NSMutableArray *arrOfTextFields = [NSMutableArray array];
      for (id subView in self.view.subviews)
      {
          if ([subView isKindOfClass:[UITextField class]])
             [arrOfTextFields addObject:subView]; 
      }
      

      【讨论】:

      • 这不会捕获嵌入在其他视图中的 UITextFields。
      【解决方案6】:

      编辑没有全局变量的递归(仅适用于 Tim)

      -(NSArray*)performUIElementSearchForClass:(Class)targetClass onView:(UIView*)root{
      
          NSMutableArray *searchCollection = [[[NSMutableArray alloc] init] autorelease];
      
          for(UIView *subview in root.subviews){
      
              if ([subView isKindOfClass:targetClass])  
                  [searchCollection addObject:subview];
      
              if(subview.subviews.count > 0)
                  [searchCollection addObjectsFromArray:[self performUIElementSearchForClass:targetClass onView:subview]];
      
          }
      
          return searchCollection;
      }
      

      【讨论】:

      • 我发现自己经常在 SO 上这样输入:NSMutableArray ]alloc] init ]autorelease XCode 宠坏了我:P
      • 这不会捕获嵌入在其他视图中的 UITextFields。
      • 递归,但使用全局变量?邪恶!
      猜你喜欢
      • 2015-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多