UIPickerView selectedRowInComponent:当我尝试在第二个组件中设置数据时,0总是先返回零
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UIPickerView selectedRowInComponent:当我尝试在第二个组件中设置数据时,0总是先返回零相关的知识,希望对你有一定的参考价值。
我是ios编程的新手。
最近,我正在尝试将UIPickerView作为UITextfield中的inputView。
UIPickerView中的数据是关于所有iOS内置字体的。所以我想在UIPickerView中创建两个组件:第一个是familyType,第二个是该familyType中的所有字体。
我模拟来自this answer的代码,但我遇到了一些我无法解决的问题。欢迎任何帮助!
我的问题在这里: 为什么这个函数中的rowOneSelected总是先得到0,即使我提前使用了selectedRowInComponent?
// The number of rows of data
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if(component == 0)
{
return _fontTypeArray.count;
}
else
{
NSInteger rowOneSelected = [_pickerFont selectedRowInComponent:0];
FontType *temp = _fontTypeArray[rowOneSelected];
NSLog(@"%ld", (long)rowOneSelected); // I use this to debug, and there is a main question: why every time it logs 0 first?
return temp.font.count;
}
}
我的所有相关代码都在这里:
在ViewController.h中:
#import <UIKit/UIKit.h>
#import "MenuLayerTwoPlusThree.h"
@interface ViewController : UIViewController
@property MenuLayerTwoPlusThree *layerTwoPlusThree;
- (void)createLayerTwoPlusThree;
@end
在ViewController.m中:
- (void)viewDidLoad {
[super viewDidLoad];
[self createLayerTwoPlusThree];
}
- (void)createLayerTwoPlusThree
{
_layerTwoPlusThree = [MenuLayerTwoPlusThree alloc];
[_layerTwoPlusThree createFontArray];
[_layerTwoPlusThree createSelectPanel];
}
在FontType.h中:
#ifndef FontType_h
#define FontType_h
#import <Foundation/Foundation.h>
@interface FontType : NSObject
@property NSString *familyName;
@property NSMutableArray *font;
@end
#endif /* FontType_h */
在FontType.m中:
#import <Foundation/Foundation.h>
#import "FontType.h"
@implementation FontType
@synthesize familyName;
@synthesize font;
@end
在MenuLayerTwoPlusThree.h中:
#ifndef MenuLayerTwoPlusThree_h
#define MenuLayerTwoPlusThree_h
#import <UIKit/UIKit.h>
#import "FontType.h"
@interface MenuLayerTwoPlusThree : NSObject<UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate>
@property UITextField *textFieldFont;
@property NSMutableArray *fontTypeArray;
@property UIPickerView *pickerFont;
@property UIBarButtonItem *doneButton;
@property UIBarButtonItem *spaceButton;
@property UIBarButtonItem *cancelButton;
@property UIToolbar *toolBar;
@property NSArray *toolBarItems;
@property NSInteger familyType;
@property NSInteger fontType;
@property NSString *fontName;
- (void)createFontArray;
- (IBAction)pickerViewButtonClicked:(id)sender;
@end
在MenuLayerTwoPlusThree.m中
- (void)createFontArray
{
_fontTypeArray = [[NSMutableArray alloc]initWithCapacity:80];
int number = 0;
for(NSString* family in [UIFont familyNames])
{
//NSLog(@"%@", family);
//number++;
FontType *temp = [[FontType alloc]init];
temp.familyName = family;
temp.font = [[NSMutableArray alloc]init];
int flag = 0;
for(NSString* name in [UIFont fontNamesForFamilyName:family])
{
//NSLog(@" %@", name);
//number++;
flag++;
[temp.font addObject:name];
}
// add Heiti SC, Heiti TC, Telugu Sangam MN, and Bangla Sangam MN to font array
if(flag == 0)
{
[temp.font addObject:family];
}
[_fontTypeArray addObject:temp];
}
// print all fonts test
for(FontType *x in _fontTypeArray)
{
number++;
NSLog(@"%@", x.familyName);
for(NSString *y in x.font)
{
//number++;
NSLog(@" %@", y);
}
}
NSLog(@"//////////////////////////////");
NSLog(@"%d", number);
}
- (void)createSelectPanel
{
[self createSelectPanelForPancel1];
[self createSelectPanelForPancel2];
[self createSelectPanelForFont];
[self createSelectPanelForShape];
[self createSelectPanelForEraser];
}
- (void)createSelectPanelForFont
{
_textFieldFont = [[UITextField alloc]initWithFrame:CGRectMake(19, 148, 150, 12)];
[_textFieldFont setBackground:[UIImage imageNamed:@"font-type-bar.png"]];
_textFieldFont.rightViewMode = UITextFieldViewModeAlways;
_textFieldFont.delegate = self;
[_textFieldFont setPlaceholder:@"Heiti TC"];
_textFieldFont.font = [_textFieldFont.font fontWithSize:10 * _aspectRatio];
// resize right view image
UIImageView *rightViewImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 12 * _aspectRatio, 12 * _aspectRatio)];
[rightViewImage setImage:[UIImage imageNamed:@"font-type-bar-roll.png"]];
_textFieldFont.rightView = rightViewImage;
_pickerFont = [[UIPickerView alloc]init];
_pickerFont.dataSource = self;
_pickerFont.delegate = self;
_pickerFont.showsSelectionIndicator = YES;
_doneButton = [[UIBarButtonItem alloc]initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(pickerViewButtonClicked:)];
_spaceButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
_cancelButton = [[UIBarButtonItem alloc]initWithTitle:@"Cancel" style:UIBarButtonItemStylePlain target:self action:@selector(pickerViewButtonClicked:)];
_toolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 45)];
[_toolBar setBarStyle:UIBarStyleDefault];
_toolBarItems = [NSArray arrayWithObjects:_cancelButton, _spaceButton, _doneButton, nil];
[_toolBar setItems:_toolBarItems];
_textFieldFont.inputView = _pickerFont;
_textFieldFont.inputAccessoryView = _toolBar;
if (@available(iOS 9.0, *)) {
_textFieldFont.inputAssistantItem.leadingBarButtonGroups = @[];
} else {
// Fallback on earlier versions
}
if (@available(iOS 9.0, *)) {
_textFieldFont.inputAssistantItem.trailingBarButtonGroups = @[];
} else {
// Fallback on earlier versions
}
// I want to add these codes to select row in advanced to make sure first time NSLog will print 9, but it doesn't work.
// [_pickerFont reloadAllComponents];
// _familyType = 9;
// _fontType = 0;
// _fontName = @"Heiti TC";
// [_pickerFont selectRow:_familyType inComponent:0 animated:YES];
[_selectPanelFontView addSubview:_textFieldFont];
}
这是委托,我在MenuLayerTwoPlusThree.m中编写:
// The number of columns of data
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
// The number of rows of data
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if(component == 0)
{
return _fontTypeArray.count;
}
else
{
NSInteger rowOneSelected = [_pickerFont selectedRowInComponent:0];
FontType *temp = _fontTypeArray[rowOneSelected];
NSLog(@"%ld", (long)rowOneSelected); // I use this to debug, and there is a main question: why every time it logs 0 first?
return temp.font.count;
}
}
// The data to return for the row and component (column) that's being passed in
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if(component == 0)
{
FontType *temp = _fontTypeArray[row];
return temp.familyName;
}
else
{
NSInteger rowOneSelected = [_pickerFont selectedRowInComponent:0];
FontType *temp = _fontTypeArray[rowOneSelected];
return [temp.font objectAtIndex:row];
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if(component == 0)
{
[_pickerFont reloadComponent:1];
}
// This block is moved to pickerViewButtonClicked (sender == _doneButton)
// else
// {
// NSInteger rowOneSelected = [_pickerFont selectedRowInComponent:0];
// FontType *temp = _fontTypeArray[rowOneSelected];
// [_textFieldFont setText:temp.font[row]];
// }
}
- (IBAction)pickerViewButtonClicked:(id)sender
{
if(sender == _doneButton)
{
// Save value when I clicked the done button.
_familyType = [_pickerFont selectedRowInComponent:0];
_fontType = [_pickerFont selectedRowInComponent:1];
// NSLog(@"family: %ld", _familyType);
// NSLog(@"font: %ld", _fontType);
FontType *temp = _fontTypeArray[_familyType];
_fontName = temp.font[_fontType];
[_textFieldFont setText:_fontName];
// NSLog(@"font name: %@", _fontName);
[_textFieldFont endEditing:YES];
}
else if(sender == _cancelButton)
{
[_textFieldFont endEditing:YES];
// I want to turn back to the last selected value when I clicked the cancel button.
[_pickerFont reloadAllComponents];
[_pickerFont selectRow:_familyType inComponent:0 animated:NO];
[_pickerFont selectRow:_fontType inComponent:1 animated:NO];
}
}
看来,当你在组件0中选择了第9行后UIPickerView
显示为inputView
时,selectedRowInComponent: 0
在numberOfRowsInComponent: 1
中返回0,但随后在titleForRow: row forComponent: 1
中返回9。
我不认为你做错了什么,所以它看起来像UIKit中的一个bug。
作为一种解决方法,我建议您不要询问所选行的选择器视图,而是自己跟踪所选行(在视图控制器中初始化您自己的变量并在didSelectRow: row inComponent: 0
中更新它)
对不起,我忘了发布我的解决方案。
我使用_fontTypeIsFirst来查看是否已选择UIPickerView。当你滚动选择器视图时,你应该将_fontTypeIsFirst设置为NO并重新加载组件1,这样它就像往常一样返回到组件1中的第0行。
这是我的代码:
一些代表:
// The number of columns of data
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
// The number of rows of data
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if(component == 0)
{
return _fontTypeArray.count;
}
else
{
NSInteger rowOneSelected;
if (_fontTypeIsFirst == YES)
{
rowOneSelected = _selectedRow;
}
else
{
rowOneSelected = [_pickerFont selectedRowInComponent:0];
}
FontType *temp = _fontTypeArray[rowOneSelected];
return temp.font.count;
}
}
// The data to return for the row and component (column) that's being passed in
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if(component == 0)
{
FontType *temp = _fontTypeArray[row];
return temp.familyName;
}
else
{
NSInteger rowOneSelected;
if (_fontTypeIsFirst == YES)
{
rowOneSelected = _selectedRow;
}
else
{
rowOneSelected = [_pickerFont selectedRowInComponent:0];
}
FontType *temp = _fontTypeArray[rowOneSelected];
return [temp.font objectAtIndex:row];
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
_fontTypeIsFirst = NO;
if(component == 0)
{
[_pickerFont reloadComponent:1];
}
}
这是完成和取消按钮的动作:
- (IBAction)pickerViewButtonClicked:(id)sender
{
if(sender == _doneButton)
{
_selectedRow = [_pickerFont selectedRowInComponent:0];
_familyType = [_pickerFont selectedRowInComponent:0];
_fontType = [_pickerFont selectedRowInComponent:1];
FontType *temp = _fontTypeArray[_familyType];
_fontName = temp.font[_fontType];
[_textFieldFont setText:_fontName];
[_textFieldFont endEditing:YES];
_fontTypeIsFirst = YES;
}
else if(sender == _cancelButton)
{
[_textFieldFont endEditing:YES];
_fontTypeIsFirst = YES;
[_pickerFont selectRow:_familyType inComponent:0 animated:NO];
[_pickerFont selectRow:_fontType inComponent:1 animated:NO];
}
}
您可以添加这样的代码来选择viewDidLoad或某个地方的选择器视图的默认值:
_fontTypeIsFirst = YES;
_selectedRow = 9;
_familyType = 9;
_fontType = 0;
_fontName = @"Heiti TC";
[_pickerFont selectRow:_familyType inComponent:0 animated:NO];
[_pickerFont selectRow:_fontType inComponent:1 animated:NO];
以上是关于UIPickerView selectedRowInComponent:当我尝试在第二个组件中设置数据时,0总是先返回零的主要内容,如果未能解决你的问题,请参考以下文章
如何从另一个 UIPickerview 更改 UIPickerView 的字符串?