Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c Interface Builder中的IBMoutletCollection集合排序_Objective C_Ios_Xcode_Interface Builder_Iboutlet - Fatal编程技术网

Objective c Interface Builder中的IBMoutletCollection集合排序

Objective c Interface Builder中的IBMoutletCollection集合排序,objective-c,ios,xcode,interface-builder,iboutlet,Objective C,Ios,Xcode,Interface Builder,Iboutlet,我正在使用IBOutletCollections对几个类似UI元素的实例进行分组。特别是我将一些UIButton(类似于智力竞赛中的蜂鸣器)和一组UILabel(显示分数)分组。我想确保按钮正上方的标签更新分数。我认为通过索引访问它们是最容易的。不幸的是,即使我以相同的顺序添加它们,它们也不总是具有相同的索引。在Interface Builder中有没有设置正确顺序的方法。据我所知,没有 作为一种解决方法,您可以按顺序为它们中的每一个分配一个标记。让按钮范围为100、101、102等,标签范围为

我正在使用IBOutletCollections对几个类似UI元素的实例进行分组。特别是我将一些UIButton(类似于智力竞赛中的蜂鸣器)和一组UILabel(显示分数)分组。我想确保按钮正上方的标签更新分数。我认为通过索引访问它们是最容易的。不幸的是,即使我以相同的顺序添加它们,它们也不总是具有相同的索引。在Interface Builder中有没有设置正确顺序的方法。

据我所知,没有

作为一种解决方法,您可以按顺序为它们中的每一个分配一个标记。让按钮范围为100、101、102等,标签范围为200、201、202等,然后将100添加到按钮的标签中,以获得相应的标签标签。然后可以使用
viewForTag:
获取标签


或者,您可以将相应的对象分组到它们自己的
UIView
,这样每个视图只有一个按钮和一个标签。

EDIT:一些评论者声称,最新版本的Xcode按照连接的顺序返回
IBOutletCollections
。其他人则声称这种方法在情节提要中不适用于他们。我自己还没有测试过,但是如果你愿意依赖未记录的行为,那么你可能会发现我下面建议的显式排序不再是必要的


不幸的是,似乎没有任何方法可以控制IB中
IBOutletCollection
的顺序,因此需要根据视图的某些属性对加载后的数组进行排序。您可以根据视图的
tag
属性对视图进行排序,但是在IB中手动设置标记可能会非常繁琐

幸运的是,我们倾向于按照访问视图的顺序排列视图,因此通常根据x或y位置对数组进行排序就足够了,如下所示:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Order the labels based on their y position
    self.labelsArray = [self.labelsArray sortedArrayUsingComparator:^NSComparisonResult(UILabel *label1, UILabel *label2) {
        CGFloat label1Top = CGRectGetMinY(label1.frame);
        CGFloat label2Top = CGRectGetMinY(label2.frame);

        return [@(label1Top) compare:@(label2Top)];
    }];
}

不确定这到底是什么时候改变的,但至少从Xcode 4.2开始,这似乎不再是一个问题。IBMoutletCollections现在保留了在Interface Builder中添加视图的顺序

更新:


我做了一个测试项目来验证这种情况:

我用cduhn的答案运行,并将这个NSArray分类。 如果现在xcode真的保留了设计时顺序,那么这段代码就不需要了,但是如果您发现自己必须在IB中创建/重新创建大型集合,并且不想担心弄糟,那么这可能会有所帮助(在运行时)。另请注意:对象添加到集合的顺序很可能与您在“标识检查器”选项卡中找到的“对象ID”有关,当您稍后编辑界面并向集合引入新对象时,该ID可能会变得零散

h

m


IBMoutletCollection的订购方式似乎非常随意。也许我没有正确理解Nick Lockwood的方法,但我还是做了一个新项目,添加了一堆UILabel,并按照添加到视图中的顺序将它们连接到一个集合

登录之后,我得到了一个随机订单。这非常令人沮丧

我的解决方法是在IB中设置标记,然后按如下方式对集合进行排序:

[self setResultRow1:[self sortCollection: [self resultRow1]]];
这里,resultRow1是一个大约7个标签的iOutletCollection,标签通过IB设置。下面是排序方法:

-(NSArray *)sortCollection:(NSArray *)toSort {
    NSArray *sortedArray;
    sortedArray = [toSort sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
        NSNumber *tag1 = [NSNumber numberWithInt:[(UILabel*)a tag]];
        NSNumber *tag2 = [NSNumber numberWithInt:[(UILabel*)b tag]];
        return [tag1 compare:tag2];
    }];

    return sortedArray;
}

为此,我现在可以使用
[resultRow1 objectAtIndex:I]
或类似工具访问对象。这节省了每次需要访问元素时必须迭代和比较标记的开销。

我需要对UITextField对象集合进行排序,以设置键盘上的“下一步”按钮将导致的位置(字段选项卡)。这将是一个国际应用程序,所以我希望语言方向是模糊的

h


我发现Xcode使用连接ID按字母顺序对集合进行排序。 如果在nib文件上打开版本编辑器,您可以轻松编辑id(确保它们是唯一的,否则Xcode将崩溃)



如果您首先在IB的文档大纲中手动对对象进行排序,以便它们在xml代码中按顺序显示,这会有所帮助。

我在
数组上创建了一个扩展,用于按
标记进行排序,例如,在使用w/
IBOutletCollection
时很有用

extension Array where Element: UIView {

  /**
   Sorts an array of `UIView`s or subclasses by `tag`. For example, this is useful when working with `IBOutletCollection`s, whose order of elements can be changed when manipulating the view objects in Interface Builder. Just tag your views in Interface Builder and then call this method on your `IBOutletCollection`s in `viewDidLoad()`.
   - author: Scott Gardner
   - seealso:
   * [Source on GitHub](http://bit.ly/SortUIViewsInPlaceByTag)
   */
  mutating func sortUIViewsInPlaceByTag() {
    sortInPlace { (left: Element, right: Element) in
      left.tag < right.tag
    }
  }

}
扩展数组,其中元素:UIView{
/**
按“标记”对“UIView”数组或子类进行排序。例如,这在使用“IBMoutletCollection”时非常有用,在界面生成器中操作视图对象时,可以更改其元素顺序。只需在界面生成器中标记视图,然后在“viewDidLoad()”中对“IBMoutletCollection”调用此方法即可。
-作者:斯科特·加德纳
-另见:
*[来源于GitHub](http://bit.ly/SortUIViewsInPlaceByTag)
*/
变异func sortUIViewsInPlaceByTag(){
sortInPlace{(左:元素,右:元素)位于
left.tag
由@scott gardner提出的扩展非常好,解决了[ui按钮]集合未按预期顺序显示等问题。以下代码仅为Swift 5更新。真的非常感谢斯科特! 扩展数组,其中元素:UIView{

  /**
   Sorts an array of `UIView`s or subclasses by `tag`. For example, this is useful when working with `IBOutletCollection`s, whose order of elements can be changed when manipulating the view objects in Interface Builder. Just tag your views in Interface Builder and then call this method on your `IBOutletCollection`s in `viewDidLoad()`.
   - author: Scott Gardner
   - seealso:
   * [Source on GitHub](bit dot ly/SortUIViewsInPlaceByTag)
   */
  mutating func sortUIViewsInPlaceByTag() {
    sort { (left: Element, right: Element) in
      left.tag < right.tag
    }
  }

}
/**
按“标记”对“UIView”数组或子类进行排序。例如,这在使用“IBMoutletCollection”时非常有用,在界面生成器中操作视图对象时,可以更改其元素顺序。只需在界面生成器中标记视图,然后在“viewDidLoad()”中对“IBMoutletCollection”调用此方法即可。
-作者:斯科特·加德纳
-另见:
*[GitHub上的源](位dotly/SortUIViewsInPlaceByTag)
*/
变异func sortUIViewsInPlaceByTag(){
在中排序{(左:元素,右:元素)
left.tag
我使用@scott gardner建议的扩展来排序图像视图,以便使用单个p来显示计数器
-(NSArray *)sortCollection:(NSArray *)toSort {
    NSArray *sortedArray;
    sortedArray = [toSort sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
        NSNumber *tag1 = [NSNumber numberWithInt:[(UILabel*)a tag]];
        NSNumber *tag2 = [NSNumber numberWithInt:[(UILabel*)b tag]];
        return [tag1 compare:tag2];
    }];

    return sortedArray;
}
#import <Foundation/Foundation.h>

@interface NSArray (UIViewSort)

- (NSArray *)sortByUIViewOrigin;

@end
#import "NSArray+UIViewSort.h"

@implementation NSArray (UIViewSort)

- (NSArray *)sortByUIViewOrigin {
    NSLocaleLanguageDirection horizontalDirection = [NSLocale characterDirectionForLanguage:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]];
    NSLocaleLanguageDirection verticalDirection = [NSLocale lineDirectionForLanguage:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]];
    UIView *window = [[UIApplication sharedApplication] delegate].window;
    return [self sortedArrayUsingComparator:^NSComparisonResult(id object1, id object2) {
        CGPoint viewOrigin1 = [(UIView *)object1 convertPoint:((UIView *)object1).frame.origin toView:window];
        CGPoint viewOrigin2 = [(UIView *)object2 convertPoint:((UIView *)object2).frame.origin toView:window];
        if (viewOrigin1.y < viewOrigin2.y) {
            return (verticalDirection == kCFLocaleLanguageDirectionLeftToRight) ? NSOrderedDescending : NSOrderedAscending;
        }
        else if (viewOrigin1.y > viewOrigin2.y) {
            return (verticalDirection == kCFLocaleLanguageDirectionLeftToRight) ? NSOrderedAscending : NSOrderedDescending;
        }
        else if (viewOrigin1.x < viewOrigin2.x) {
            return (horizontalDirection == kCFLocaleLanguageDirectionTopToBottom) ? NSOrderedDescending : NSOrderedAscending;
        }
        else if (viewOrigin1.x > viewOrigin2.x) {
            return (horizontalDirection == kCFLocaleLanguageDirectionTopToBottom) ? NSOrderedAscending : NSOrderedDescending;
        }
        else return NSOrderedSame;
    }];
}

@end
- (void)viewDidAppear:(BOOL)animated {
    _availableTextFields = [_availableTextFields sortByUIViewOrigin];

    UITextField *previousField;
    for (UITextField *field in _availableTextFields) {
        if (previousField) {
            previousField.nextTextField = field;
        }
        previousField = field;
    }
}
<outletCollection property="characterKeys" destination="QFa-Hp-9dk" id="aaa-0g-pwu"/>
<outletCollection property="characterKeys" destination="ahU-9i-wYh" id="aab-EL-hVT"/>
<outletCollection property="characterKeys" destination="Kkl-0x-mFt" id="aac-0c-Ot1"/>
<outletCollection property="characterKeys" destination="Neo-PS-Fel" id="aad-bK-O6z"/>
<outletCollection property="characterKeys" destination="AYG-dm-klF" id="aae-Qq-bam"/>
<outletCollection property="characterKeys" destination="Blz-fZ-cMU" id="aaf-lU-g7V"/>
<outletCollection property="characterKeys" destination="JCi-Hs-8Cx" id="aag-zq-6hK"/>
<outletCollection property="characterKeys" destination="DzW-qz-gFo" id="aah-yJ-wbx"/>
extension Array where Element: UIView {

  /**
   Sorts an array of `UIView`s or subclasses by `tag`. For example, this is useful when working with `IBOutletCollection`s, whose order of elements can be changed when manipulating the view objects in Interface Builder. Just tag your views in Interface Builder and then call this method on your `IBOutletCollection`s in `viewDidLoad()`.
   - author: Scott Gardner
   - seealso:
   * [Source on GitHub](http://bit.ly/SortUIViewsInPlaceByTag)
   */
  mutating func sortUIViewsInPlaceByTag() {
    sortInPlace { (left: Element, right: Element) in
      left.tag < right.tag
    }
  }

}
  /**
   Sorts an array of `UIView`s or subclasses by `tag`. For example, this is useful when working with `IBOutletCollection`s, whose order of elements can be changed when manipulating the view objects in Interface Builder. Just tag your views in Interface Builder and then call this method on your `IBOutletCollection`s in `viewDidLoad()`.
   - author: Scott Gardner
   - seealso:
   * [Source on GitHub](bit dot ly/SortUIViewsInPlaceByTag)
   */
  mutating func sortUIViewsInPlaceByTag() {
    sort { (left: Element, right: Element) in
      left.tag < right.tag
    }
  }

}
self.dayDigits.sortUIViewsInPlaceByTag()

func updateDayDigits(countString: String){
        for i in 0...4 {
            dayDigits[i].image = offDigitImage
        }
        let length = countString.count - 1
        for i in 0...length {
            let char = Array(countString)[length-i]
            dayDigits[i].image = digitImages[char.wholeNumberValue!]
        }
    }