Giustificare UIViews su iPhone: Algorithm Aiuto
-
22-09-2019 - |
Domanda
Sono stato nei guai con un modo per giustificare allineare un insieme di sottoclassi UIView all'interno di una vista che contiene. Sto avendo un po 'di problemi con l'algoritmo e speravo che qualcuno potesse aiutare a individuare i miei errori. Ecco pseudocodice di dove mi trovo ora:
// 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)];
}
Gli elementi non sembrano essere distanziati in modo uniforme qui. Neanche vicino. Dove sto andando male?
Ecco un colpo di questo algoritmo in azione: alt text http://grab.by/1Wcg
EDIT: Il codice di cui sopra è pseudocodice. Ho aggiunto il codice vero e proprio qui, ma potrebbe non avere senso se non si ha familiarità con il progetto 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
Soluzione
Sono riuscito a farlo funzionare da solo! Stavo applicando il margine di sbagliato agli elementi. Il problema è che ho dovuto applicare il margine tenendo conto del precedente elementi di origine e larghezza.
@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
Altri suggerimenti
coneybeare, grazie per capire questo fuori, ma la vostra soluzione in realtà non funzionare come previsto. Cambia la posizione di schede sulla barra, ma la spaziatura non è giusto. Questo sembra funzionare meglio per me:
#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, ho anche avuto parecchi errori di compilazione. Avevo bisogno di importare UIViewAdditions.h e dirgli che è un super-TTTabStrip.