iOS 7 UIPickerView 非选中行曲率修改多个组件

Posted

技术标签:

【中文标题】iOS 7 UIPickerView 非选中行曲率修改多个组件【英文标题】:iOS 7 UIPickerView non-selected row curvature modification multiple components 【发布时间】:2013-11-07 00:24:30 【问题描述】:

我正在尝试修改 UIPickerView 曲率,使其看起来像 ios 7 计时器。

这是我所拥有的:

请注意 2 和 4 如何与所选行中的 3 显着偏移。有没有办法让它更“平坦”,就像 iOS7 中的 la Timer,其中 2 和 4 直接位于 3 的上方和下方?

这是我迄今为止尝试过的:

    玩弄- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component

    在内部使用自定义 UIView 和自定义 UILabel 偏移量

似乎没有一个工作。

有什么帮助吗?

【问题讨论】:

您是如何添加“ft”和“in”这些标签的?我正在寻找一种方法来做到这一点 @DCDC - 标签只是使用 UILabel 覆盖在选择器顶部。 【参考方案1】:

偏移是由于选择器指示器所在的单独的凸起平面造成的。这实际上是对这种现实生活视角(嵌套、印刷、透明的圆柱体)的相当准确的渲染。 Apple 在时钟应用程序中所做的是右对齐选择器标签。这可确保数字与其单位标签之间的间距保持不变。你可以做同样的事情。

首先,在您的选择器视图委托中,您希望实现 -pickerView:attributedTitleForRow:forComponent: 来代替 -pickerView:titleForRow:forComponent:。 (看起来你已经完成了白色文本颜色。)你将使用 NSParagraphStyle 字符串属性。您需要在段落样式上设置两个属性:对齐和尾部缩进。对齐方式应设置为 NSTextRightAlignment。尾部对齐将取决于您希望标签离组件右边缘多远。如果您有多个组件,则需要使用 -pickerView:widthForComponent: 设置组件的宽度。如果您想将曲率保持在最低限度,请将组件宽度设置为尾缩进的大约两倍。

注意:如果您的选择器恰好有两个组件,则每个组件的宽度必须小于选择器宽度的 ⅓。

这是一个代码示例:

- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component

    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    [paragraphStyle setAlignment:NSTextAlignmentRight];
    [paragraphStyle setTailIndent:150];

    return [[NSAttributedString alloc] initWithString:@"42"
                                           attributes:@NSParagraphStyleAttributeName:paragraphStyle];


- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component

    return 300;

【讨论】:

很抱歉,您的 NSTextAlignment 解决方案不起作用。曲率仍然非常突出。您是否验证了您的解决方案? 我忘了提到要让这个解决方案与 多个 组件一起使用,组件宽度需要设置为尾缩进值的大约两倍。我已经用详细信息更新了我的答案。 另外,为了正确显示,选择器正好有两个组件的组件有一个最大宽度。 看来是你的笔记成功了。将两个组件的宽度设置为 100 是不同的。不需要段落样式或缩进。【参考方案2】:

改为2个组件,尝试做4个组件,类似这个sn-p:

- (void)viewDidLoad

    [super viewDidLoad];
     self.model  = @[@"1",@"2",@"3",@"4",@"5",@"6"];



- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView

    return 4;


- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component

    NSInteger numberOfRows;
    if(component == 0 || component == 2)
    
        numberOfRows = [self.model count];
    
    else
    
        numberOfRows = 1;
    
    return numberOfRows;

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component

    NSString* title;
    switch (component) 
        case 0:
        case 2:
            title = self.model[row];
            break;
        case 1:
            title = @"ft";
            break;
        case 3:
            title = @"in";
            break;
        default:
            break;
    
    return title;

【讨论】:

将单元放置在单独的组件中很优雅,但是如何防止单元上的滚动运动? Apple 没有提供禁用选择器段反弹的接口,因为它违反了它的 HIG。通过 HIG,所有视图都应该有反弹,因为这样用户就知道这是路的尽头,没有任何东西被堆积。因此,我们无法在没有一些 hack 的情况下禁用分段弹跳,或者您可以在带有单位的分段上添加透明视图并禁用其上的用户交互。 其他解决方案是您已经尝试过的,在它们之外有 2 个选择器和单元,或者作为值的一部分。 @Igor 但苹果时钟中的单位不反弹。我也在尝试禁用单位的反弹。 如果还有人在看这篇文章medium.com/@luisfmachado/uipickerview-fixed-labels-66f947ded0a8【参考方案3】:

我通过使用修复了布局问题

- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component
    switch (component)
        case 0:
            return 106.0f;
        case 1:
            return 50.0f;
        case 2:
            return 106.0f;
    
    return 0;

https://***.com/a/19743682/809671

当 UIPickerView 组件的大小大于 106 时,链接显示布局中断。所以我将部分宽度设置为 106。

我通过使 UIPicker 有 3 个组件在中间添加了空间。

【讨论】:

【参考方案4】:

我注意到如果组件数== 1,那么就没有这种缩放+偏移的效果了。

我为解决此问题而实施的 hack 是在屏幕上显示 2 个 UIPickerView 并相应地实施委托和数据源功能。

【讨论】:

这个工作的原因是选择器标签居中对齐。当您将组件设置为 1 时,这可确保组件居中对齐,从而确保透视对齐。这不是时钟应用程序中处理问题的方式。如果您仔细观察,您会发现 Apple 已将标签对齐。有关操作方法,请参阅 my answer。 @Endersstocker,您的解决方案对我不起作用。你在 iOS 7 上验证了吗? 这是在iOS 7上设计和使用的一种方法。我相信这也是Apple在Clock应用中使用的方法。

以上是关于iOS 7 UIPickerView 非选中行曲率修改多个组件的主要内容,如果未能解决你的问题,请参考以下文章

UIPickerView 选择行不起作用 ios7

iOS 7 用 UIPickerView 打开 UITableViewController 很慢

如何获取UIPickerView中选中的cell的值

未选中的 UIPickerView 值

UIPickerView 不会立即重绘未选中的行

如何在 iOS Swift 3 中滚动到 UIPickerView 中的特定行