I am using IBOutletCollections to group several Instances of similar UI Elements. In particular I group a number of UIButtons (which are similar to buzzers in a quiz game) a
I needed this ordering for a collection of UITextField objects for setting where the "Next" button on the keyboard would lead to (field tabbing). This is going to be an international app so I wanted the language direction to be ambiguous.
.h
#import
@interface NSArray (UIViewSort)
- (NSArray *)sortByUIViewOrigin;
@end
.m
#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
Usage (after layout)
- (void)viewDidAppear:(BOOL)animated {
_availableTextFields = [_availableTextFields sortByUIViewOrigin];
UITextField *previousField;
for (UITextField *field in _availableTextFields) {
if (previousField) {
previousField.nextTextField = field;
}
previousField = field;
}
}