【问题标题】:backgroundImage on UIButton scales wronglyUIButton 上的 backgroundImage 缩放错误
【发布时间】:2012-11-17 00:36:06
【问题描述】:

当用户按下按钮然后为宽度设置动画时,我试图给我的 UIButton 一个新的背景图像。问题是按钮不缩放图像(我只使用视网膜图像)。

点击前:

点击后:

以及使事情发生的代码:

UIImage *buttonProfileDefault = [[UIImage imageNamed:@"Profile_Button_Default"] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 3, 3)];
        [self.profileButton setBackgroundImage:buttonProfileDefault forState:UIControlStateNormal];

[self.profileButton removeConstraint:self.profileButtonConstraint];

// Animate
CGRect originalFrame = self.profileButton.frame;
originalFrame.size.width = 40;
[UIView animateWithDuration:0.2f
    animations:^{
        self.profileButton.frame = originalFrame;
    }
        completion:^(BOOL finished) {
    }];

【问题讨论】:

  • 我希望我们能解决这个问题:我也有同样的问题。我已经尝试了所有 contentMode 选项和所有 imageEdgeInsets(对于那些我将背景图像移动到按钮图像中的那些,它覆盖或消除了按钮标题)都无济于事。
  • 我会悬赏这个。真的需要知道。
  • @HolgerEdwardWardlowSindbæk 试试我的代码...

标签: iphone objective-c ios xcode storyboard


【解决方案1】:

试试这个代码...

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:1.0];
    [self.profileButton setBackgroundImage:[UIImage imageNamed:@"Profile_Button_Default"] forState:UIControlStateNormal];
    [self.profileButton setBackgroundImage:[UIImage imageNamed:@"Profile_Button_Default"] forState:UIControlStateSelected];
    [self.profileButton setFrame:CGRectMake(self.profileButton.frame.origin.x, self.profileButton.frame.origin.y, self.profileButton.frame.size.width + 40, self.profileButton.frame.size.height)];
    [UIView commitAnimations];

希望对你有帮助……

【讨论】:

    【解决方案2】:

    创建边缘插入的方式将保持最左边的 3 个和最右边的 3 个点(或像素)不变,并且会拉伸按钮上的头部。如果您希望头部的大小保持不变,则必须将其包含在左侧,保留 1 个像素可拉伸,然后是右侧。假设你的图片宽度是 50,你会这样写:

    UIImage * buttonProfileDefault = [[UIImage imageNamed:@"Profile_Button_Default"] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 46, 3, 3)];

    但是,这会使您的图片位于按钮的左侧。我推荐的解决方案是使用 2 张图片:

    1. 仅包含按钮边框的可调整大小的图像,设置为按钮的背景图像
    2. 仅包含头部的图像,设置为固定大小的按钮图像

    代码如下所示:

    UIImage *backgroundImage = [[UIImage imageNamed:@"border.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 3, 3)]; // in this case you can use 3, 3, 3, 3

    [self.profileButton setBackgroundImage:backgroundImage forState:UIControlStateNormal];

    UIImage *titleImage = [UIImage imageNamed:@"head.png"];

    [self.profileButton setImage:titleImage forState:UIControlStateNormal];

    希望这会有所帮助!

    【讨论】:

    • 这是一个很好的观察。但这不是问题。一开始,我将背景图像切换为没有头部的图像(问题在那里解决了),但它没有使用帽插入,所以边缘变得扭曲和奇怪。那就是问题所在!感谢您的意见。
    • 图片的原始尺寸是多少?
    • 70 x 58(我只为视网膜和非视网膜 iPhone 使用视网膜版本)
    【解决方案3】:

    我在以下几点修改了您的代码:

    • 提供图片 Profile_Button_Default.png(或 .jpg 等)的完整名称,
    • 在正常情况下为图像添加了状态,这些效果不会出现在开始触摸按钮时

    现在检查:

    UIImage *buttonProfileDefault = [[UIImage imageNamed:@"Profile_Button_Default.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 3, 3)];
    [self.profileButton setBackgroundImage:buttonProfileDefault forState:UIControlStateNormal];
    [self.profileButton setBackgroundImage:buttonProfileDefault
                                  forState:UIControlStateSelected];
    [self.profileButton setBackgroundImage:buttonProfileDefault forState:UIControlStateHighlighted];
    
    [self.profileButton removeConstraint:self.profileButtonConstraint];
    
    // Animate
    CGRect originalFrame = self.profileButton.frame;
    originalFrame.size.width = 40;
    [UIView animateWithDuration:0.2f
                     animations:^{
                         self.profileButton.frame = originalFrame;
                     }
                     completion:^(BOOL finished) {
                     }];
    

    【讨论】:

      【解决方案4】:

      我认为问题在于您更改背景然后调整大小。

      让它与自动布局一起工作的关键是为 widthConstraint 常量值设置动画,并在动画中设置背景图像。

      例如,我的视图名称上有一个按钮 button,我的宽度约束有一个名为 buttonWidth 的 IBOutlet - 下面是我的 buttonPress 的代码 :

      UIImage *imageButton = [[UIImage imageNamed:@"button"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 10, 0, 10)];
      
      [UIView animateWithDuration:0.01f
                       animations:^{
                           [self.button setBackgroundImage:imageButton forState:UIControlStateNormal];
                       }
                       completion:^(BOOL finished) {
                           [UIView animateWithDuration:1.0f
                                            animations:^{
                                                self.buttonWidth.constant = 300;
                                                [self.view layoutIfNeeded];
                                            }
                                            completion:^(BOOL finished) {
                                            }];
      
      
                       }];
      

      正如您在上面的代码中看到的那样,让它对我有用的关键是在动画中设置按钮背景,由于某种原因,如果我在动画之外更改了背景图像,它不会正确设置它,直到动画完成。

      在使用 autoLayout 时设置框架也不适合我,所以我为约束常量设置了动画

      【讨论】:

        【解决方案5】:

        试试这个,而不是将图像分配为

        UIImage *buttonProfileDefault = [[UIImage imageNamed:@"Profile_Button_Default"] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 3, 3)];
        

        这样做

        UIImage *buttonProfileDefault = [UIImage imageNamed:@"Profile_Button_Default"];
        

        无需设置 resizableImageWithCapInsets 的约束。

        【讨论】:

          【解决方案6】:

          您不能复制图像并将其调整为正确的按钮大小吗?

          post. 中查看 IWasRobbed 的答案

          他在那里为你提供了一个很好的功能,并声称将这种方法用于他的按钮。

          【讨论】:

          • 用于按钮图像可能是合理的,但我发现这些方法使用的内存比我想要的更大图像要多得多。它会在 Activity Monitor 工具中显示一个巨大的峰值,并且我不断收到很多内存警告。
          【解决方案7】:

          我遇到了同样的问题,但是当我的应用程序加载时发生了,我在检查器中弄乱了 button 的属性,如果你向下滚动并取消选中 autoresize subviews 它可能会起作用,它确实给我!

          【讨论】:

          • 我非常希望这会为我解决同样的问题,但它没有。我的背景图像是由 UIImageView 的子类派生的,不过,像这样:[self setBackgroundImage:[backgroundImageView image] forState:UIControlStateNormal];
          • @tobinjim 您是否尝试将其样式属性从普通更改为自定义?
          • @Shinigamae 我认为我的一直是自定义的。我最终放弃了使用 UIButton 子类的想法,转而使用处理触摸的 UIView 子类。我最初喜欢 UIButton 类,因为标题文本带有控制状态;但是当我测试我的程序时,标题更改如此突然变得很烦人,所以在我的 UIView 子类中,我处理相同的消息,但过渡时会快速淡出和淡入变化的文本。
          【解决方案8】:

          在使用笔尖时,我也遇到过类似的情况来调整子视图的大小。不确定您是否是,但解决我的问题的是在我的各种视图中取消选中“使用自动布局”。

          【讨论】:

          • 这可能会解决问题,但我想使用自动布局。如果您取消选中它,它适用于整个应用程序!
          • AutoLayout 选择仅适用于您选中或取消选中它的笔尖。你可以有几个使用自动布局的笔尖,有些不在同一个应用程序中使用自动布局
          猜你喜欢
          • 2011-08-11
          • 2015-01-04
          • 1970-01-01
          • 1970-01-01
          • 2011-04-09
          • 2013-05-25
          • 2010-12-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多