使用 UIAppearance 自定义 iOS UIDatepicker

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10844675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:34:50  来源:igfitidea点击:

Custom iOS UIDatepicker using UIAppearance

iphoneiosios5uidatepickeruiappearance

提问by daidai

UNIQLO's new alarm apphas a custom UIDatePicker:

优衣库的新闹钟应用有一个自定义UIDatePicker

custom

风俗

And I want to create my own custom UIDatePicker.

我想创建自己的自定义UIDatePicker.

I tried to change the appearance of the DatePicker, but looking for UI_APPEARANCE_SELECTORin the UIDatePickerreturns nothing.

我试图改变 DatePicker 的外观,但UI_APPEARANCE_SELECTORUIDatePicker返回什么都没有寻找。

Meaning that its not possible to change any values, as per the docs:

根据文档,这意味着无法更改任何值:

To support appearance customization, a class must conform to the UIAppearanceContainer protocol and relevant accessor methods must be marked with UI_APPEARANCE_SELECTOR.

为了支持外观定制,一个类必须符合 UIAppearanceContainer 协议,并且相关的访问器方法必须用 UI_APPEARANCE_SELECTOR 标记。

How can change my UIDatePicker's appearance?

怎样才能改变我UIDatePicker的容貌?

回答by Kuldeep

The API does not provide a way to do this. You can make a pretty convincing replica yourself using a UIPickerView rather than using UIDatePicker.

API 不提供执行此操作的方法。您可以使用 UIPickerView 而不是使用 UIDatePicker 自己制作一个非常有说服力的副本。

As the UIDatePicker or UIPickerView don't have the UI_APPEARANCE_SELECTOR and even you can't change UIDatePicker contents' appearance as its UIControl and not having any delegate so it has its native appearance whereas in case of UIPickerView you can change its contents' appearance similar as in UITableView.

由于 UIDatePicker 或 UIPickerView 没有 UI_APPEARANCE_SELECTOR 甚至你不能改变 UIDatePicker 内容的外观作为它的 UIControl 并且没有任何委托所以它有它的原生外观,而在 UIPickerView 的情况下你可以改变它的内容的外观类似于在 UITableView 中。

#pragma mark -
#pragma mark UIPicker Delegate & DataSource

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

// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    return 100;
}
//- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:  (NSInteger)component {
     //    return [NSString stringWithFormat:@"%d",row];
//}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {

      UILabel *label= [[[UILabel alloc] initWithFrame:CGRectMake(30.0, 0.0, 50.0, 50.0)] autorelease];
      [label setBackgroundColor:[UIColor clearColor]];
      [label setTextColor:[UIColor blueColor]];
      [label setFont:[UIFont boldSystemFontOfSize:40.0]];
      [label setText:[NSString stringWithFormat:@"%d",row]];

      return label;
}

enter image description here

在此处输入图片说明

Check this out.

看一下这个。

回答by Roger

add this method in your implementation file

在您的实现文件中添加此方法

-(UIView *)pickerViews{

    return ([datePicker.subviews objectAtIndex:0]);
}

-(void)viewDidLoad{

    [super viewDidLoad];

    [[self pickerViews].subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSLog(@"%@ --- > %i",obj, idx);
    }];
}

when you run your app it will display all the subviews of the datePicker on your console, just choose any index and modify them one by one

当您运行您的应用程序时,它会在您的控制台上显示 datePicker 的所有子视图,只需选择任何索引并一一修改它们即可

modify the viewDidLoad and insert this code

修改 viewDidLoad 并插入此代码

UIView *background = (UIView *)[[self pickerViews].subviews objectAtIndex:0];
background.backgroundColor = [UIColor clearColor];

UIView *wheel2 = (UIView *)[[self pickerViews].subviews objectAtIndex:4];
wheel2.backgroundColor = [UIColor redColor];

UIView *wheel3 = (UIView *)[[self pickerViews].subviews objectAtIndex:11];
wheel3.backgroundColor = [UIColor redColor];

In this case i change the background color of index "0", "4", "11"

在这种情况下,我更改索引“0”、“4”、“11”的背景颜色

回答by Scott Berrevoets

With iOS 5 the UIAppearanceprotocol was introduced, which lets you customize several UI elements. UIDatePicker happens to conform this protocol, so that is probably the easiest way to do this. That is, if you're willing to support only iOS 5 users. Matthew's option would probably the next best thing, which should also work with older iOS versions.

iOS 5引入了UIAppearance协议,它允许您自定义多个 UI 元素。UIDatePicker 恰好符合这个协议,所以这可能是最简单的方法。也就是说,如果您愿意仅支持 iOS 5 用户。马修的选项可能是下一个最好的选择,它也适用于较旧的 iOS 版本。

回答by marzapower

It appears to be quite difficult to change the way a UIDatePickerappears.

似乎很难改变 a 的UIDatePicker出现方式。

The example you provided, in my opinion, is a sophisticated customization of a simple UIPickerViewwith two columns and probably a simulated infinite scroll (as Apple does in the date picker, and it's quite simple to realize).

在我看来,您提供的示例是对简单UIPickerView的两列和可能的模拟无限滚动的复杂定制(就像 Apple 在日期选择器中所做的那样,实现起来非常简单)。

You can change little of the UIDatePickerthrough the UIAppearanceproxy, as seen in this example:

您可以UIDatePicker通过UIAppearance代理更改很少的内容,如下例所示:

UIDatePicker *picker = [UIDatePicker appearance];
picker.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.3];

UIView *view;
view = [UIView appearanceWhenContainedIn:[UITableView class], [UIDatePicker class], nil];
view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];

UILabel *label = [UILabel appearanceWhenContainedIn:[UITableView class], [UIDatePicker class], nil];
label.font = [UIFont systemFontOfSize:[UIFont systemFontSize]];
label.textColor = [UIColor blueColor];

Using this piece of code at the start of the application (just try it) you can change the aspect of only a couple of the main components of the date picker.

在应用程序开始时使用这段代码(尝试一下),您可以仅更改日期选择器的几个主要组件的方面。

Labels are impossibleto customize (and this test code proves it); apparently they are changed in aspect every time you rotate a column, since they are put inside a custom UITableViewcontroller.

标签无法自定义(此测试代码证明了这一点);显然,每次旋转列时它们的外观都会发生变化,因为它们被放置在自定义UITableView控制器中。

To fully change these appearances you should probably work with private APIs from Apple, that will eventually result in your app being rejected.

要完全改变这些外观,您可能应该使用 Apple 的私有 API,这最终会导致您的应用被拒绝

If you just need a custom hour-minute picker (as shown in your screenshot), the full customization of appearance is reachable only extending the UIPickerViewclass or assigning an appropriate delegate to a UIPickerViewinstance.

如果您只需要一个自定义的小时-分钟选择器(如您的屏幕截图所示),则只有扩展UIPickerView类或为UIPickerView实例分配适当的委托才能完全自定义外观。

Through the

通过

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

method on the delegate you can make the single element of the picker view appear the way you want. Then you will have to appropriately handle the data source to make the two components of the picker virtually infinite.

委托上的方法,您可以使选择器视图的单个元素以您想要的方式显示。然后,您必须适当地处理数据源,以使选取器的两个组件几乎无限。

回答by Matthew Gillingham

You can implement one yourself using two UIScrollViews, one for hours and one for minutes. You would just need to figure out the contentOffset of each scrollview when it has stopped moving, which off the top of my head would look like this:

您可以使用两个 UIScrollViews 自己实现一个,一个用于小时,一个用于分钟。当每个滚动视图停止移动时,您只需要弄清楚它的 contentOffset ,我的头顶看起来像这样:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
  if (!decelerate) {
    // get the offset here
  }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
  // also get the offset here
}

Take the value of the content offset and translate it into the hour value and minute value, probably by dividing the y position of the content offset by the 24 or 60 respectively. You will need to make the custom artwork yourself.

获取内容偏移量的值并将其转换为小时值和分钟值,可能是将内容偏移量的 y 位置分别除以 24 或 60。您需要自己制作自定义艺术品。

回答by Oleh Kudinov

To change date picker color:

要更改日期选择器颜色:

[datePickerView setValue:self.pickerLabelColor forKey:@"textColor"];

And to change font the only way I know is:

我所知道的唯一改变字体的方法是:

Create category UIFont+Systemand place this code inside

创建类别UIFont+System并将此代码放入其中

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
    + (UIFont *)systemFontOfSize:(CGFloat)fontSize
    {
        return [UIFont fontWithName:fontName size:fontSize];
    }
#pragma clang diagnostic pop

This will set as well fonts in another places in your app (replacing system font by your font).

这也会在您的应用程序的其他位置设置字体(用您的字体替换系统字体)。

回答by IronManGill

You should go through the UICatalog by Apple. It has all the methods in which a UIDatePicker can be used including the custom date picker method . Study this link developer.apple.com/library/ios/samplecode/UICatalog/ . Also they have implemented a standard switch and the navigation bar which is given in the latter.

您应该浏览 Apple 的 UICatalog。它具有可以使用 UIDatePicker 的所有方法,包括自定义日期选择器方法。研究这个链接 developer.apple.com/library/ios/samplecode/UICatalog/ 。他们还实现了标准开关和后者中给出的导航栏。

回答by Vimal Venugopalan

A combination of 2 UITableViewsis the way to go.

2的组合UITableViews是要走的路。

UITableViewis a subview of UIScrollView, so it handles the following event

UITableView是 的子视图UIScrollView,因此它处理以下事件

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{

}

and on getting the position, just scroll the table to the center using the following method

并在获得位置时,只需使用以下方法将表格滚动到中心

[myTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES];

Hope this helps.

希望这可以帮助。