如何在iOS中创建一个大的、红色的UIButton?

53

如何在iOS上创建一个类似于iPhone删除联系人时使用的红色“删除”按钮?


这个问题非常接近你的问题,并且包含了几种生成带颜色按钮的方法。 - Brad Larson
我最近也做了这个,为此创建了一个按钮(以及一些Monotouch示例代码供任何Monotoucher使用):alt text 它的斜角较小,在任何背景下都能更好地工作,但与iPhone的UIGlassButton不完全匹配。 - Chris S
我已经在我的网站上添加了一些按钮图像,这些图像在MIT许可证下可以免费使用,并且更接近iOS玻璃按钮。(但是由于我是新手,这个论坛不允许我发布图片)要下载它们并获取示例代码,请访问: http://www.geneticmistakes.com/articles/1000/stretchable-dynamic-images-for-buttons - RicMoo
2
这里是完整的内置iOS资源:https://github.com/pixelfreak/iOS-UI-Assets - pixelfreak
6个回答

84

首先,您需要一个可拉伸的图像:

alt文本 http://grab.by/4lP

然后,您可以使用该可拉伸的图像作为背景来创建一个按钮,并添加文本。

UIButton *sampleButton = [UIButton buttonWithType:UIButtonTypeCustom];
[sampleButton setFrame:CGRectMake(kLeftMargin, 10, self.view.bounds.size.width - kLeftMargin - kRightMargin, 52)];
[sampleButton setTitle:@"Button Title" forState:UIControlStateNormal];
[sampleButton setFont:[UIFont boldSystemFontOfSize:20]];
[sampleButton setBackgroundImage:[[UIImage imageNamed:@"redButton.png"] stretchableImageWithLeftCapWidth:10.0 topCapHeight:0.0] forState:UIControlStateNormal];
[sampleButton addTarget:self action:@selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:sampleButton];

显然,您需要调整框架的原点和大小以匹配您的应用程序,以及目标、选择器和标题。


好的解决方案。只需要一个代码修复:你忘记在-[UIImage imageNamed:]中的字符串前面加上@符号了。 - Jonathan Sterling
注意:安东尼的问题在此得到解答:http://stackoverflow.com/questions/2276099/a-big-green-uiimage-anyone/2276272 - amphetamachine
优秀的文章 - 感谢提供免费图片,我会使用它 :) - Steve Neal
我认为这已经过时了,因为UIButton的'setFont'已被弃用。但仍然是一个好答案。 - Popeye
stretchableImageWithLeftCapWidth:topCapHeight:在5.0中已被弃用,推荐使用resizableImageWithCapInsets: - Nate

62

我还制作了一些按钮...包括retina版本和非retina版本

如果你想在单元格中使用它们,请在cellForRowAtIndexPath中使用以下代码:

UIButton *sampleButton = [UIButton buttonWithType:UIButtonTypeCustom];
[sampleButton setFrame:[cell.contentView frame]];
[sampleButton setFrame:CGRectMake(0, 0, cell.bounds.size.width-20, 44)];
[sampleButton setBackgroundImage:[UIImage imageNamed:@"button_red.png"] forState:UIControlStateNormal];
[cell addSubview:sampleButton];

Green Button Normal

Red Button Normal

Grey Button Normal

Green Button Retina Red Button Retina Grey Button Retina


1
你有这些图片的透明背景版本吗?当我将它们放在一个非白色背景的视图中时,它看起来很奇怪...你知道我的意思吗? - Henley
2
@Hisoka:sampleButton.alpha = 0.5; - titaniumdecoy
非常好。这些是从iPhone的GUI中获取的吗? - Matej

22

我认为这些图片更好(而且它们在视网膜显示器上看起来也很好):

alt text alt text

这些 .png 文件是从这个非常棒的 .psd 文件生成的: http://www.teehanlax.com/blog/2010/08/12/iphone-4-gui-psd-retina-display/

然后将其用作您的 UIButton 的背景可拉伸图像:

UIImage* greenButton = [UIImage imageNamed:@"UIButton_green.png"]; 
UIImage *newImage = [greenButton stretchableImageWithLeftCapWidth:greenButton.size.width/2 topCapHeight:greenButton.size.height/2];
[callButton setBackgroundImage:newImage forState:UIControlStateNormal];


请注意,在应用程序中使用这些内容会违反原作者的许可证。 - Daniel Beck
1
请注意,链接已经过期,您会看到“页面未找到”的提示。显然这不是您的错,但如果您有新的链接,可以更新一下链接吗?谢谢。 - Popeye

2

最简单的方法可能是获取这个包含许多UI元素的PSD文件(iPhone GUI Photoshop file),然后在Photoshop中改变大按钮的色调并将其保存为PNG格式。

这种方法的一个优点是您还可以创建按下和/或高亮状态的版本,并将图像分配给标准的UIButton。


一个缺点是你需要在捆绑包中保留大量的大图像,而它们在不同的旋转下不适合屏幕。 - coneybeare

0

你可以在分组表视图中创建一个单独的部分,只给该部分一个行,并将该单元格的背景图像设置为红色渐变图像。不过,你需要自己重新创建那个图像。


虽然这样做是有效的,但它不像我提出的解决方案那样可定制。如果您想要特殊的高亮显示或状态,您需要实现自定义逻辑,而苹果已在UIButton类中包含了这些逻辑。 - coneybeare

0
我想提供一种解决方案,它不使用图像,但是可以使联系人中的“删除”按钮具有相同的外观。 在下面的示例中,假设使用Storyboard设计的带有分组、静态单元格的UITableView。让其中一个部分仅具有单个单元格。该单元格将成为“删除”按钮。给单元格一个红色背景颜色(例如,红色221,绿色0,蓝色2)。
我们要做的是向单元格添加两个GradientLayers。第一个将覆盖单元格的上半部分。第二个将覆盖下半部分。
将QuartzCore添加到您的实现文件中:
#import <QuartzCore/QuartzCore.h>

从这个单元格开始创建一个插座:

@property (strong, nonatomic) IBOutlet UITableViewCell *cellDelete;

创建一个方法,用于格式化单元格:
- (void)formatCellDelete
{
    // Top Gradient //
    CAGradientLayer *gradientTop = [CAGradientLayer layer];

    // Make a frame for the layer based on the size of the cells contentView
    // Make it half the height
    // The width will be -20 so the gradient will not overflow
    CGRect frame = CGRectMake(0, 0, _cellDelete.contentView.frame.size.width - 20, _cellDelete.contentView.frame.size.height / 2);
    gradientTop.frame = frame;

    gradientTop.cornerRadius = 8;

    UIColor* topColor = [UIColor colorWithWhite:1.0f alpha:0.75f];
    UIColor* bottomColor = [UIColor colorWithWhite:1.0f alpha:0.0f];
    gradientTop.colors = [NSArray arrayWithObjects:(id)[topColor CGColor], (id)[bottomColor CGColor], nil];

    [_cellDelete.contentView.layer setMasksToBounds:YES];
    [_cellDelete.contentView.layer insertSublayer:gradientTop atIndex:0];



    // Bottom Gradient //
    CAGradientLayer *gradientBottom = [CAGradientLayer layer];

    // Make a frame for the layer based on the size of the cells contentView
    // Make it half the height
    // The width will be -20 so the gradient will not overflow
    frame = CGRectMake(0, 0, _cellDelete.contentView.frame.size.width - 20, _cellDelete.contentView.frame.size.height / 2);
    // And move to bottom
    frame.origin.y = frame.size.height;
    gradientBottom.frame = frame;

    topColor = [UIColor colorWithWhite:0.0f alpha:0.05f]; //0.20
    bottomColor = [UIColor colorWithWhite:0.0f alpha:0.0f];
    gradientBottom.colors = [NSArray arrayWithObjects:(id)[topColor CGColor], (id)[bottomColor CGColor], nil];

    [_cellDelete.contentView.layer setMasksToBounds:YES];
    [_cellDelete.contentView.layer insertSublayer:gradientBottom atIndex:0];


    // Define a selected-backgroundColor so the cell changes color when the user tabs it
    UIView *bgColorView = [[UIView alloc] init];
    [bgColorView setBackgroundColor:[UIColor colorWithRed:(float)(0.502) green:0.0 blue:0.0 alpha:1.000]];
    bgColorView.layer.cornerRadius = 10;
    [_cellDelete setSelectedBackgroundView:bgColorView];
}

以上代码将使您的单元格看起来像联系人中的“删除”按钮一样具有玻璃外观。 但我们还希望在用户点击它时更改其颜色。这就是上述方法中最后一段代码所做的事情。它将设置一个不同的视图,其中包含较暗的颜色作为selectedBackgroundView。

点击单元格后,它将保持选定状态并保持其深色。要自动取消选择单元格,我们执行以下操作:

从一个常量开始,该常量定义了您的删除单元格的部分编号:

static NSInteger const SECTION_DELETE = 1;

现在实现 (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 方法(定义在 UITableViewDelegate 中):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    if(indexPath.section == SECTION_DELETE){

        [tableView deselectRowAtIndexPath:indexPath animated:YES];
    }


    // Navigation logic may go here. Create and push another view controller.
    /*
      *detailViewController = [[ alloc] initWithNibName:@"" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     */

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接