Cocoa 带有自定义固定标签和自动布局的UiPickerView

Cocoa 带有自定义固定标签和自动布局的UiPickerView,cocoa,uipickerview,Cocoa,Uipickerview,我需要实现一个UIPickerView来选择小时、分钟和秒。我需要有一个标签,旁边的每个组件保持固定时,选择器旋转。例如,您可以查看Apple Clock应用程序的计时器部分。我放了一张图片作为参考 当然我需要一个有3个部件的选择器,但问题是一样的。我找到了很多解决方案,可以将标签添加为子视图,并使用一些框架和手动调整来定位它,但a无法使其与AutoLayout一起工作,而且我在web上也找不到解决方案。有人解决了这个问题吗?谢谢我在自己开发的一个应用程序中遇到了类似的问题,并决定: 一,。创

我需要实现一个
UIPickerView
来选择小时、分钟和秒。我需要有一个标签,旁边的每个组件保持固定时,选择器旋转。例如,您可以查看Apple Clock应用程序的计时器部分。我放了一张图片作为参考


当然我需要一个有3个部件的选择器,但问题是一样的。我找到了很多解决方案,可以将标签添加为子视图,并使用一些框架和手动调整来定位它,但a无法使其与AutoLayout一起工作,而且我在web上也找不到解决方案。有人解决了这个问题吗?谢谢

我在自己开发的一个应用程序中遇到了类似的问题,并决定:

一,。创建UIPicker

二,。找到显示的选择器行的中点

iii.在屏幕和-
(void)布局子视图中添加两个UILabel确保标签始终位于中点旁边

在我的项目中,我只需要纵向模式支持,但在横向模式下也应该可以很好地工作。只需选择足够宽的行宽度,这样就不会与选择器内的数据有任何重叠。下面是UIPicker的一段代码:

#pragma mark - Picker View

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 2;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    if(component == 0) {
        return self.hourPickerData.count;
    } else {
        return self.minutePickerData.count;
    }
}

- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
    return 40;
}

- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component
{
    return 30;
}

-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
    NSString *text;

    if(component == 0) {
        text = self.hourPickerData[row];
    } else {
        text = self.minutePickerData[row];
    }

    UILabel *label = (UILabel*)view;
    if(view == nil) {
        label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 30)];
        label.backgroundColor = [UIColor clearColor];
        label.text = text;
        label.textAlignment = NSTextAlignmentCenter;
        label.textColor = LYTiT_HEADER_COLOR;
        label.font = [UIFont fontWithName:LT_HELVETICA size:16];
    }

    return label;
} 

我认为其他人可以从我的补充回答中受益

对于i组件,应在pickerView初始化方法(viewDidLoad)中包含以下内容:


Swift 4.2

创建pickerView后添加下一个代码:

// Fixed labels
let font = UIFont.systemFont(ofSize: 20.0)
let fontSize: CGFloat = font.pointSize
let componentWidth: CGFloat = self.view.frame.width / CGFloat(agePickerView.numberOfComponents)
let y = (agePickerView.frame.size.height / 2) - (fontSize / 2)

let label1 = UILabel(frame: CGRect(x: componentWidth * 0.65, y: y, width: componentWidth * 0.4, height: fontSize))
label1.font = font
label1.textAlignment = .left
label1.text = "Years"
label1.textColor = UIColor.lightGray
agePickerView.addSubview(label1)

let label2 = UILabel(frame: CGRect(x: componentWidth * 1.65, y: y, width: componentWidth * 0.4, height: fontSize))
label2.font = font
label2.textAlignment = .left
label2.text = "Years"
label2.textColor = UIColor.lightGray
agePickerView.addSubview(label2)

let label3 = UILabel(frame: CGRect(x: componentWidth * 0.05, y: 0, width: componentWidth , height: fontSize))
label3.font = font
label3.textAlignment = .center
label3.text = "From"
label3.textColor = UIColor.lightGray
agePickerView.addSubview(label3)

let label4 = UILabel(frame: CGRect(x: componentWidth * 0.95, y: 0, width: componentWidth , height: fontSize))
label4.font = font
label4.textAlignment = .center
label4.text = "To"
label4.textColor = UIColor.lightGray
agePickerView.addSubview(label4)

自动布局有什么特别的原因吗?通过简单的方法是不可能的,因为picker视图的内部没有公开,所以针对内部层次结构创建约束很容易出错,不建议这样做。在这种情况下,我将对一个
UIPickerView
(像苹果的
UIDatePicker
)进行子类化,并使用计算出的帧位置实现所有逻辑。我理解你的观点,因此问题不再是自动布局“如何实现一个
UIPickerView
子类,该子类适用于各种屏幕大小,也适用于记录的横向和纵向屏幕方向,苹果的UIDatePicker不是UIPickerView的子类。我不理解你提出的解决方案。@Luca-你能详细说明你不理解的部分吗?我需要在“UIPickerView”的每个组件旁边有一个固定标签,我不知道如何从Apple documentation:LayoutSubview-如果您需要比约束或自动调整大小行为提供的更精确地控制子视图的布局,请实现此方法。此方法在自动布局发生后调用,以便您可以将它们一起使用。基本的想法是,你预先知道你的拾取者的高度,因此你知道你的拾取者的中点。由于您还知道每个组件的宽度(您自己在委托方法中指定了此宽度),因此您知道标签的位置,以便它们准确地显示在正确的位置。@AceGreen我没有写出该方法,因为从描述中应该可以清楚地看到如何实现它。但是,如果您在这样做时遇到任何问题,请告诉我。一个代码示例可以指出您的确切问题,这会很有帮助:)
// Fixed labels
let font = UIFont.systemFont(ofSize: 20.0)
let fontSize: CGFloat = font.pointSize
let componentWidth: CGFloat = self.view.frame.width / CGFloat(agePickerView.numberOfComponents)
let y = (agePickerView.frame.size.height / 2) - (fontSize / 2)

let label1 = UILabel(frame: CGRect(x: componentWidth * 0.65, y: y, width: componentWidth * 0.4, height: fontSize))
label1.font = font
label1.textAlignment = .left
label1.text = "Years"
label1.textColor = UIColor.lightGray
agePickerView.addSubview(label1)

let label2 = UILabel(frame: CGRect(x: componentWidth * 1.65, y: y, width: componentWidth * 0.4, height: fontSize))
label2.font = font
label2.textAlignment = .left
label2.text = "Years"
label2.textColor = UIColor.lightGray
agePickerView.addSubview(label2)

let label3 = UILabel(frame: CGRect(x: componentWidth * 0.05, y: 0, width: componentWidth , height: fontSize))
label3.font = font
label3.textAlignment = .center
label3.text = "From"
label3.textColor = UIColor.lightGray
agePickerView.addSubview(label3)

let label4 = UILabel(frame: CGRect(x: componentWidth * 0.95, y: 0, width: componentWidth , height: fontSize))
label4.font = font
label4.textAlignment = .center
label4.text = "To"
label4.textColor = UIColor.lightGray
agePickerView.addSubview(label4)