iOS - UIPickerView文字大小颜色修改,无限轮播,无限循环滚动

最近项目里用到了UIPickerView,要求无限轮播,简单看了看UIPickView的所有属性和所有代理方法,没有无限轮播的设置,遂去百度了一把,发现网上流传着一个帖子,大家各种转载,看了看后,明白其中道理,原来是这样!

UIPickerView,使用规则与UITableView很像,下边是UIPickerView的.h文件,包涵两个代理的描述:

//
//  UIPickerView.h
//  UIKit
//
//  Copyright (c) 2006-2015 Apple Inc. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
#import <UIKit/UIView.h>
#import <UIKit/UIKitDefines.h>

NS_ASSUME_NONNULL_BEGIN

@protocol UIPickerViewDataSource, UIPickerViewDelegate;

NS_CLASS_AVAILABLE_IOS(2_0) __TVOS_PROHIBITED @interface UIPickerView : UIView <NSCoding>

@property(nullable,nonatomic,weak) id<UIPickerViewDataSource> dataSource;                // default is nil. weak reference
@property(nullable,nonatomic,weak) id<UIPickerViewDelegate>   delegate;                  // default is nil. weak reference
@property(nonatomic)        BOOL                       showsSelectionIndicator;   // default is NO

// info that was fetched and cached from the data source and delegate
@property(nonatomic,readonly) NSInteger numberOfComponents;
- (NSInteger)numberOfRowsInComponent:(NSInteger)component;
- (CGSize)rowSizeForComponent:(NSInteger)component;

// returns the view provided by the delegate via pickerView:viewForRow:forComponent:reusingView:
// or nil if the row/component is not visible or the delegate does not implement 
// pickerView:viewForRow:forComponent:reusingView:
- (nullable UIView *)viewForRow:(NSInteger)row forComponent:(NSInteger)component;

// Reloading whole view or single component
- (void)reloadAllComponents;
- (void)reloadComponent:(NSInteger)component;

// selection. in this case, it means showing the appropriate row in the middle
- (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated;  // scrolls the specified row to center.

- (NSInteger)selectedRowInComponent:(NSInteger)component;                                   // returns selected row. -1 if nothing selected

@end


__TVOS_PROHIBITED
@protocol UIPickerViewDataSource<NSObject>
@required

// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;

// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
@end

__TVOS_PROHIBITED
@protocol UIPickerViewDelegate<NSObject>
@optional

// returns width of column and height of row for each component. 
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component __TVOS_PROHIBITED;
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component __TVOS_PROHIBITED;

// these methods return either a plain NSString, a NSAttributedString, or a view (e.g UILabel) to display the row for the component.
// for the view versions, we cache any hidden and thus unused views and pass them back for reuse. 
// If you return back a different object, the old one will be released. the view will be centered in the row rect  
- (nullable NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component __TVOS_PROHIBITED;
- (nullable NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED; // attributed title is favored if both methods are implemented
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(nullable UIView *)view __TVOS_PROHIBITED;

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component __TVOS_PROHIBITED;

@end

NS_ASSUME_NONNULL_END

你会发现,其中方法很少,也很容易理解,我不做过多解释。我们接着说文字大小和颜色的修改~

注意代理又一个这样的方法:

- (nullable NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED; // attributed title is favored if both methods are implemented

OK,就是这个,这个方法返回一个NSAttributedString类型数据,这个数据在我的微博里已经转载了一篇详细文章:http://blog.csdn.net/icefishlily/article/details/52692141

上代码:

- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component {
    NSDictionary* titleTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                         kCL6, NSForegroundColorAttributeName,
                                         [UIFont systemFontOfSize:30.0f], NSFontAttributeName,
                                         nil];
    
    NSInteger count = self.dataList.count;
    NSString *str = [NSString stringWithFormat:@"%.1f%%", [self.dataList[row%count] doubleValue]];
    NSAttributedString *restr = [[NSAttributedString alloc] initWithString:str attributes:titleTextAttributes];
    return restr;
}
用了上边这个方法,就不要用下边的方法了。
- (nullable NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component __TVOS_PROHIBITED;

注意上边代码中字典的定义,用到了两个东西:

NSForegroundColorAttributeName  文字颜色值
NSFontAttributeName             文字font

 

好了,不用多说了,颜色和大小搞定了。

接着说无限轮播,其实UIPickerView是个假的无限轮播,其原理是将你需要展示的几个cell(这里暂且叫cell,好理解)复制很多份(例如200份),然后都放到UIPickerView里边展示,并且在pickerView最开始出现的时候,就让它默认拨到中间位置,这样上下都有100组同样的数据,在不滑倒边界时,就像是无限轮播了。

代码如下:

        //下边代码放在初始化的位置即可
        self.dataList = [[NSMutableArray alloc] init];
        for (int i=0; i<=20; i++) {
            [self.dataList addObject:[NSNumber numberWithDouble:i*0.1]];
        }
        //拨到中间位置
        [self.pickView selectRow:self.dataList.count*100 inComponent:0 animated:YES];

//下边代码是UIPickerView的部分代理
#pragma mark UIPickerViewDelegate, UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
    return 1;
    
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    return self.dataList.count * 200;
}

- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component {
    NSDictionary* titleTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                         kCL6, NSForegroundColorAttributeName,
                                         [UIFont systemFontOfSize:30.0f], NSFontAttributeName,
                                         nil];
    
    NSInteger count = self.dataList.count;
    NSString *str = [NSString stringWithFormat:@"%.1f%%", [self.dataList[row%count] doubleValue]];
    NSAttributedString *restr = [[NSAttributedString alloc] initWithString:str attributes:titleTextAttributes];
    return restr;
}








  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用 `UITextViewDelegate` 中的 `textViewDidChangeSelection` 方法来实现通过选择器(`UIPickerView`)选择颜色和字体大小后,选中文本后文字和字体颜色的改变。 首先,您需要创建一个 `UIPickerView` 并将其作为 `UITextView` 的 inputView,以便用户可以在选择器中选择颜色和字体大小。具体做法如下: ```swift // 创建一个 UIPickerView let pickerView = UIPickerView() pickerView.delegate = self pickerView.dataSource = self // 将 pickerView 设置为 textView 的 inputView yourTextView.inputView = pickerView ``` 然后,您需要在 `UITextViewDelegate` 中的 `textViewDidChangeSelection` 方法中获取所选文本的范围,并将选定的文本的颜色和字体属性设置为选择器中选择的值。具体实现代码如下: ```swift func textViewDidChangeSelection(_ textView: UITextView) { let selectedRange = textView.selectedRange let attributedText = NSMutableAttributedString(attributedString: textView.attributedText) attributedText.addAttribute(.foregroundColor, value: selectedColor, range: selectedRange) attributedText.addAttribute(.font, value: selectedFont, range: selectedRange) textView.attributedText = attributedText } ``` 其中,`selectedColor` 和 `selectedFont` 分别是从选择器中获取的颜色和字体大小。 最后,您需要实现 `UIPickerViewDelegate` 和 `UIPickerViewDataSource` 协议中的方法来设置选择器的选项和响应选择器的选择事件。具体实现代码如下: ```swift // 实现 UIPickerViewDataSource 协议中的方法 func numberOfComponents(in pickerView: UIPickerView) -> Int { return 2 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { if component == 0 { return colors.count } else { return fontSizes.count } } // 实现 UIPickerViewDelegate 协议中的方法 func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { if component == 0 { return colors[row] } else { return fontSizes[row] } } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { if component == 0 { selectedColor = UIColor(named: colors[row]) ?? .black } else { selectedFont = UIFont.systemFont(ofSize: CGFloat(fontSizes[row])) ?? UIFont.systemFont(ofSize: 16) } } ``` 其中,`colors` 和 `fontSizes` 是您自定义颜色和字体大小选项数组,`selectedColor` 和 `selectedFont` 是您用来存储所选颜色和字体大小的变量。 这样,当用户选中文本后,就可以通过选择器来改变选中文本的颜色和字体大小了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值