2010-01-24 8 views
0

Je me suis amusé avec un moyen de justifier l'alignement d'une collection de sous-classes UIView dans une vue contenant. J'ai un peu de mal avec l'algorithme et espérais que quelqu'un pourrait aider à repérer mes erreurs. Voici le pseudo-code de l'endroit où je suis maintenant:Justifier UIVIews sur l'iPhone: Algorithm Help

// 1 see how many items there are 
int count = [items count]; 

// 2 figure out how much white space is left in the containing view 
float whitespace = [containingView width] - [items totalWidth]; 

// 3 Figure out the extra left margin to be applied to items[1] through items[count-1] 
float margin = whitespace/(count-1); 

// 4 Figure out the size of every subcontainer if it was evenly split 
float subcontainerWidth = [containingView width]/count; 

// 5 Apply the margin, starting at the second item 
for (int i = 1; i < [items count]; i++) { 
    UIView *item = [items objectAtIndex:i]; 
    [item setLeftMargin:(margin + i*subcontainerWidth)]; 
} 

Les items ne semblent pas être espacés uniformément ici. Pas même proche. Où vais-je mal?

Voici un coup de cet algorithme en action: alt text http://grab.by/1Wcg

EDIT: Le code ci-dessus est pseudocode. J'ai ajouté le code réel ici, mais il pourrait ne pas avoir de sens si vous n'êtes pas familier avec le projet de trois20.

@implementation TTTabStrip (JustifiedBarCategory) 
- (CGSize)layoutTabs { 
    CGSize size = [super layoutTabs]; 

    CGPoint contentOffset = _scrollView.contentOffset; 
    _scrollView.frame = self.bounds; 
    _scrollView.contentSize = CGSizeMake(size.width + kTabMargin, self.height); 

    CGFloat contentWidth = size.width + kTabMargin; 
    if (contentWidth < _scrollView.size.width) { 
     // do the justify logic 

     // see how many items there are 
     int count = [_tabViews count]; 

     // 2 figure out how much white space is left 
     float whitespace = _scrollView.size.width - contentWidth; 

     // 3 increase the margin on those items somehow to reflect. it should be (whitespace)/count-1 
     float margin = whitespace/(count-1); 

     // 4 figure out starting point 
     float itemWidth = (_scrollView.size.width-kTabMargin)/count; 
     // apply the margin 
     for (int i = 1; i < [_tabViews count]; i++) { 
      TTTab *tab = [_tabViews objectAtIndex:i]; 
      [tab setLeft:(margin + i*itemWidth)]; 
     } 

    } else { 
     // do the normal, scrollbar logic 
     _scrollView.contentOffset = contentOffset; 
    } 
    return size; 
} 
@end 
+0

Salut. Puisque toutes vos valeurs (margin et subcontainerWidth) sont calculées avant la boucle et ne changent pas au fur et à mesure de l'exécution de la boucle, l'appel à setLeftMargin est considéré comme le coupable possible. Comment fonctionne setLeftMargin? (Je ne trouve pas de document pour cela!) – deanWombourne

+0

Quelle est la différence entre containerView et containingView? Il semble que item soit une vue personnalisée car setLeftMargin n'est pas dans les documents d'Apple. Pouvez-vous poster un peu plus de code, surtout cette méthode? –

+0

containsView et containerView sont les mêmes. C'était une faute de frappe. Rappelez-vous, ceci est juste un pseudocode. Je vais poster le code actuel, mais cela n'a pas de sens parce que j'utilise trois20. – coneybeare

Répondre

0

J'ai réussi à le faire fonctionner tout seul! J'appliquais la marge mal aux éléments. Le problème est que j'avais besoin d'appliquer la marge tout en tenant compte de l'origine et de la largeur des éléments précédents.

@implementation TTTabStrip (JustifiedBarCategory) 
- (CGSize)layoutTabs { 
    CGSize size = [super layoutTabs]; 

    CGPoint contentOffset = _scrollView.contentOffset; 
    _scrollView.frame = self.bounds; 
    _scrollView.contentSize = CGSizeMake(size.width + kTabMargin, self.height); 

    CGFloat contentWidth = size.width + kTabMargin; 
    if (contentWidth < _scrollView.size.width) { 
     // do the justify logic 

     // see how many items there are 
     int count = [_tabViews count]; 

     // 2 figure out how much white space is left 
     float whitespace = _scrollView.size.width - contentWidth; 

     // 3 increase the margin on those items somehow to reflect. it should be (whitespace)/count-1 
     float margin = whitespace/(count-1); 

     // apply the margin 
     for (int i = 1; i < [_tabViews count]; i++) { 
      // 4 figure out width from the left edge to the right of the 1st element 
      float start = [[_tabViews objectAtIndex:i-1] frame].origin.x + [[_tabViews objectAtIndex:i-1] frame].size.width; 

      TTTab *tab = [_tabViews objectAtIndex:i]; 
      [tab setLeft:(start + margin)]; 
     } 
    } else { 
     // do the normal, scrollbar logic 
     _scrollView.contentOffset = contentOffset; 
    } 
    return size; 
} 
@end 
0

coneybeare, merci d'avoir compris cela, mais votre solution ne fonctionne pas vraiment comme prévu. Il change la position des onglets sur la barre, mais l'espacement n'est pas correct. Cela semble fonctionner mieux pour moi:

#import "TTTabStrip+Justify.h" 
#import <Three20UI/UIViewAdditions.h> 

// Width returned by [super layoutTabs] is always 10 px more than sum of tab widths 
static CGFloat const kContentWidthPadding = 10; 
// Adds fixed margin to left of 1st tab, right of last tab 
static CGFloat const kHorizontalMargin = 5; 

@implementation TTTabStrip (JustifyCategory) 

- (CGSize)layoutTabs { 
    CGSize size = [(TTTabStrip*)super layoutTabs]; 

    CGPoint contentOffset = _scrollView.contentOffset; 
    _scrollView.frame = self.bounds; 
    _scrollView.contentSize = CGSizeMake(size.width, self.height); 

    CGFloat contentWidth = size.width - kContentWidthPadding + 2 * kHorizontalMargin; 
    if (contentWidth < _scrollView.size.width) { 
     // do the justify logic 

     // see how many items there are 
     int count = [_tabViews count]; 

     // calculate remaining white space 
     float whitespace = _scrollView.size.width - contentWidth; 

     // calculate necessary spacing between tabs 
     float spacing = whitespace/(count + 1);  

     // apply the spacing 
     for (int i = 0; i < count; i++) { 
      CGFloat lastTabRight = kHorizontalMargin; 

      if (i > 0) { 
       TTTab *lastTab = [_tabViews objectAtIndex:i-1]; 
       lastTabRight = [lastTab right]; 
      } 

      TTTab *tab = [_tabViews objectAtIndex:i]; 
      [tab setLeft:(lastTabRight + spacing)]; 
     } 

    } else { 
     // do the normal, scrollbar logic 
     _scrollView.contentOffset = contentOffset; 
    } 
    return size; 
} 

@end 

Morgz, j'ai également eu plusieurs erreurs de compilateur. J'avais besoin d'importer UIViewAdditions.h et lui dire que super est un TTTabStrip.