在 iPhone 上证明 UIVIews 的合理性:算法帮助

发布于 2024-08-19 04:45:08 字数 2206 浏览 12 评论 0原文

我一直在研究一种方法来证明在包含视图中对齐 UIView 子类集合的合理性。我在算法方面遇到了一些麻烦,希望有人能帮助发现我的错误。这是我现在所在位置的伪代码:

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

这里的项目似乎分布不均匀。甚至还没有接近。我哪里错了?

这是该算法的实际操作截图: 替代文本http://grab.by/1Wcg

编辑:上面的代码是伪代码。我在这里添加了实际的代码,但如果您不熟悉 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

I have been messing around with a way to justify align a collection of UIView subclasses within a containing view. I am having a little bit of trouble with the algorithm and was hoping someone could help spot my errors. Here is pseudocode of where I am now:

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

The items do not appear to be evenly spaced here. Not even close. Where am I going wrong?

Here is a shot of this algorithm in action:
alt text http://grab.by/1Wcg

EDIT: The code above is pseudocode. I added the actual code here but it might not make sense if you are not familiar with the three20 project.

@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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如果没有 2024-08-26 04:45:08

我自己就能让它工作了!我对元素应用了错误的边距。问题是我需要在考虑前面的元素原点和宽度的同时应用边距。

@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

I was able to get it to work on my own! I was applying the margin wrong to the elements. The issue is that I needed to apply the margin while considering the previous elements origin and width.

@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
醉城メ夜风 2024-08-26 04:45:08

coneybeare,感谢您解决这个问题,但您的解决方案并没有真正按预期工作。它改变了栏上选项卡的位置,但间距不正确。这似乎对我来说效果更好:

#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,我也遇到了几个编译器错误。我需要导入 UIViewAdditions.h 并告诉它 super 是一个 TTTabStrip。

coneybeare, thanks for figuring this out, but your solution doesn't really work as expected. It changes the position of tabs on the bar, but the spacing is not right. This seems to work better for 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, I also got several compiler errors. I needed to import UIViewAdditions.h and tell it that super is a TTTabStrip.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文