在 Xcode 中创建按钮
Posted
技术标签:
【中文标题】在 Xcode 中创建按钮【英文标题】:Creating buttons in Xcode 【发布时间】:2013-11-02 00:58:56 【问题描述】:有没有更好的方法在 Xcode for iPhone 应用程序中执行以下操作?
我有一个主导航 UIViewController 屏幕,上面有 4 个按钮。
单击按钮 1 会显示一个带有 4 个按钮的子导航 UIViewController。 单击按钮 2 会显示相同的子导航 UIViewController,但上面有 5 个按钮。 单击按钮 3 会显示相同的子导航 UIViewController,但上面有 4 个按钮。 单击按钮 4 会显示相同的子导航 UIViewController,但上面有 6 个按钮。
为了处理这个问题,我为主导航中的每个按钮分配了标签。 当一个按钮被点击时,我把这个标签号传递给子导航 UIViewController。
然后在子导航UIViewController中,根据这个值,我根据需要手动绘制/创建子导航按钮。
下面是我如何在子导航 UIViewController 中处理这个问题。 我检查从主导航 UIViewController 传递了什么值,并相应地绘制按钮的数量。我还为每个按钮设置了自定义背景图像。对于每个按钮单击,我都有自己的选择器方法。请注意,子导航中的某些按钮将转到 UIViewController,而某些按钮将转到 TableViewController。此外,每个子导航按钮都必须在其目标视图中显示自己的“内容”。
有没有更好、更优雅的处理方式?对我来说,这似乎是很多代码重复。为简洁起见,下面的示例被缩短了。
// SubNavViewController.m
// SegueTest
#import "SubNavViewController.h"
#import "GettingHereViewController.h"
#import "TableViewController.h"
#import "GettingHereContent.h"
@interface SubNavViewController ()
@end
@implementation SubNavViewController
@synthesize tagNumber;
@synthesize buttonNumber;
@synthesize buttonPushedTrackNumber;
@synthesize hotelButton;
@synthesize bAndBButton;
@synthesize caravanButton;
@synthesize selfCateringButton;
@synthesize apartmentsButton;
.
.
.
etc (19 in total)
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
return self;
- (void)viewDidLoad
[super viewDidLoad];
if (self.tagNumber == 1)
self.navigationItem.title = @"Getting Here";
// By Air Button
byAirButton = [UIButton buttonWithType:UIButtonTypeCustom];
byAirButton.tag = 1;
byAirButton.frame = CGRectMake(25, 140, 280.f, 40.f);
UIImage *airButton = [UIImage imageNamed:@"gettingHereByAirButton.png"];
[byAirButton setBackgroundImage:airButton forState:UIControlStateNormal];
[self.view addSubview:byAirButton];
[byAirButton addTarget:self action:@selector(byAirButtonClicked) forControlEvents:UIControlEventTouchUpInside];
// By Rail Button
byRailButton = [UIButton buttonWithType:UIButtonTypeCustom];
byRailButton.tag = 2;
byRailButton.frame = CGRectMake(25, 190, 280.f, 40.f);
UIImage *railButton = [UIImage imageNamed:@"gettingHereByRailButton.png"];
[byRailButton setBackgroundImage:railButton forState:UIControlStateNormal];
[self.view addSubview:byRailButton];
[byRailButton addTarget:self action:@selector(byRailButtonClicked) forControlEvents:UIControlEventTouchUpInside];
.
.
. etc (2 more button)
else if (self.tagNumber == 2)
self.navigationItem.title = @"Where to Stay";
// B&B Button
bAndBButton = [UIButton buttonWithType:UIButtonTypeCustom];
bAndBButton.tag = 1;
bAndBButton.frame = CGRectMake(25, 140, 280.f, 40.f);
UIImage *bedAndBreakfast = [UIImage imageNamed:@"whereToStayBedAndBreakfastButton.png"];
[bAndBButton setBackgroundImage:bedAndBreakfast forState:UIControlStateNormal];
[self.view addSubview:bAndBButton];
[bAndBButton addTarget:self action:@selector(bAndBButtonClicked) forControlEvents:UIControlEventTouchUpInside];
.
.
. etc (do this for the rest of the buttons)
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
- (void) byAirButtonClicked
GettingHereContent *gettingHere = [GettingHereContent new];
gettingHere = @"By Air";
NSLog(@"Content: %@", gettingHere);
[self performSegueWithIdentifier:@"gettingHereSegue" sender:self];
- (void) bAndBButtonClicked
GettingHereContent *gettingHere = [GettingHereContent new];
gettingHere = @"Bed and Breakfast";
NSLog(@"Content: %@", gettingHere);
[self performSegueWithIdentifier:@"tableViewSegue" sender:self];
.
.
. (do this for all buttons - 19 in total)
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
@end
【问题讨论】:
这可以简化多少取决于您的 4 个子导航视图控制器中是否有任何重叠。其中一些按钮与其他按钮相同吗?某些按钮是否与相同的控制器相连,或者它们都不同?您可以简化的一件事是删除所有 @synthesize 语句,它们不再需要。 所有按钮都会有所不同,但大多数按钮会连接到同一个控制器。只有 4 个按钮会连接到不同的控制器。此外,我尝试删除所有 @synthesize 语句,但出现大量错误,因此暂时将它们保留。 您可能会遇到这些错误,因为您将属性称为 hotelButton,例如 - 如果您正在访问该属性,则需要使用 self.hotelButton,如果您想访问支持,则需要使用 _hotelButton直接使用 ivar。 【参考方案1】:首先,我建议创建一个 NS_ENUM,以下列方式定义所有按钮:
typedef NS_ENUM(NSUInteger, ButtonTag)
ButtonTagHotel,
ButtonTagOther,
...
然后在 viewDidLoad: 您可以创建一个包含所有按钮的数组,这些按钮是您当前状态所需的,如下所示:
NSMutableArray *buttonTags = [[NSMutableArray alloc] init];
if (self.tagNumber == 1 || self.tagNumber == 3)
[buttonTags addObject: @(ButtonTagHotel)];
if (self.tagNumber == 5 || self.tagNumber == 8)
[buttonTags addObject: @(ButtonTagOther)];
// etc...
当你建立了你需要的按钮标签后,你可以在一个循环中创建和添加它们:
uint cnt = 0;
for (NSNumber *tag in buttonTags)
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.tag = [tag unsignedIntValue];
btn.frame = CGRectMake(25, 20 + (cnt * 50.f), 280.f, 40.f);
UIImage *image = [UIImage imageNamed:@"genericButtonImage.png"];
[btn setBackgroundImage:image forState:UIControlStateNormal];
[self.view addSubview:btn];
[btn addTarget:self action:@selector(buttonTouched:) forControlEvents:UIControlEventTouchUpInside];
cnt++;
如果您必须为每个按钮设置不同的图像,那么您应该创建另一个数组来保存由 ButtonTag 枚举索引的所有图像名称...
现在你只需要实现 -(void)buttonTouched:(UIButton*)sender:
-(void)buttonTouched:(UIButton*)sender
switch (sender.tag)
case ButtonTagHotel:
// do your stuff
break;
...
default:
break;
【讨论】:
以上是关于在 Xcode 中创建按钮的主要内容,如果未能解决你的问题,请参考以下文章
如何在情节提要中创建一个按钮以启动在 xcode swift 中使用 spritekit 创建的游戏