在 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 创建的游戏

在标签栏 xcode 中创建展示案例视图

在 Swift 3.0 中创建 AppDelegate 后后退按钮消失

我需要帮助使用 Swift 在视图控制器中创建两个单选按钮

如何在 xcode 中创建“删除”操作表?

Xcode - 按钮增量标签