Pregunta

He estado jugando con una forma de justificar alinear un conjunto de subclases UIView dentro de una vista que contiene. Estoy teniendo un poco de problemas con el algoritmo y estaba esperando que alguien podría ayudar a detectar mis errores. Aquí es pseudocódigo de donde estoy ahora:

// 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)];
}

Los elementos no parecen estar espaciados uniformemente aquí. Ni siquiera cerca. ¿Dónde voy mal?

Aquí está una foto de este algoritmo en acción: alt text http://grab.by/1Wcg

EDIT: El código anterior es pseudocódigo. He añadido el código real aquí, pero es posible que no tienen sentido si no está familiarizado con el proyecto Three20.

@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
¿Fue útil?

Solución

Yo era capaz de conseguir que el trabajo por mi cuenta! Yo estaba aplicando mal el margen a los elementos. La cuestión es que tenía que aplicar el margen teniendo en cuenta el origen de elementos anterior y anchura.

@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

Otros consejos

Coneybeare, gracias por calcular esto, pero su solución no funciona muy bien como se esperaba. Se cambia la posición de lengüetas de la barra, pero la separación no es correcto. Esto parece funcionar mejor para mí:

#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, también tiene varios errores de compilación. Necesitaba importar UIViewAdditions.h y decirle que es un súper TTTabStrip.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top