为什么这个代码适用于iPhone 5,4和4但不适用于5s?

时间:2014-04-01 16:31:00

标签: ios iphone objective-c

我有以下代码,可以在项目中添加一些UIBarButton。这适用于以下情况:

全部在iOS 7.1上

  • 模拟器iPhone Retina 3.5英寸;
  • 模拟器iPhone Retina 4英寸;
  • 模拟器iPhone Retina 4英寸(64位)
  • Iphone 4
  • iPhone 4s

我没有iPhone 5设备可供测试。

它不适用于新的iPhone 5s。有什么不同?

以下是代码:

    -(void)setupNavigationBar
{
    self.saveSearchButton =  [UIButton buttonWithType:UIButtonTypeCustom];
    [self.saveSearchButton setImage:[UIImage imageNamed:@"Save Search"] forState:UIControlStateNormal];
    [self.saveSearchButton setImage:[UIImage imageNamed:@"Save Search Active"] forState:UIControlStateHighlighted|UIControlStateSelected];
    [self.saveSearchButton addTarget:self action:@selector(saveSearchButtonpressed)forControlEvents:UIControlEventTouchUpInside];
    [self.saveSearchButton setFrame:CGRectMake(0, 0, 23, 31)];

     self.changeLayutButton =  [UIButton buttonWithType:UIButtonTypeCustom];
    [self.changeLayutButton setImage:[UIImage imageNamed:@"View List"] forState:UIControlStateNormal];
    [self.changeLayutButton setImage:[UIImage imageNamed:@"View Grid"] forState:UIControlStateHighlighted|UIControlStateSelected];
    [self.changeLayutButton addTarget:self action:@selector(changeViewLayoutButtonPressed)forControlEvents:UIControlEventTouchUpInside];
    [self.changeLayutButton setFrame:CGRectMake(0, 0, 23, 31)];

    self.sortByButton =  [UIButton buttonWithType:UIButtonTypeCustom];
    [self.sortByButton setImage:[UIImage imageNamed:@"Sort By"] forState:UIControlStateNormal];
    [self.sortByButton setImage:[UIImage imageNamed:@"Sort By Active"] forState:UIControlStateHighlighted|UIControlStateSelected];
    [self.sortByButton addTarget:self action:@selector(sortByButtonPressed)forControlEvents:UIControlEventTouchUpInside];
    [self.sortByButton setFrame:CGRectMake(0, 0, 23, 31)];

    UIBarButtonItem *fixedItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    fixedItem.width = 20;

    UIBarButtonItem *saveSearchButton = [[UIBarButtonItem alloc] initWithCustomView:self.saveSearchButton];
    UIBarButtonItem *changeViewButton = [[UIBarButtonItem alloc] initWithCustomView:self.changeLayutButton];
    UIBarButtonItem *sortByButton = [[UIBarButtonItem alloc] initWithCustomView:self.sortByButton];


    NSArray *barbuttonitems = @[sortByButton, fixedItem, changeViewButton, fixedItem,saveSearchButton];

    self.navigationItem.rightBarButtonItems = barbuttonitems;

    self.lastLayoutUsed = [[NSUserDefaults standardUserDefaults]objectForKey:@"LastLayoutUsed"];

    if ([self.lastLayoutUsed isEqualToString:@"GridLayout"]){
        self.changeLayutButton.selected = YES;
        [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(highlightButton:) userInfo:self.changeLayutButton repeats:NO];
    }
}

我已经完成了代码,所有属性都不是零并且具有有效值。我也检查过所有图像都是正确的一面。

如何在模拟器上的每台设备上运行,而不是真正的iPhone 5S?

另外,由于这两款手机(iPhone 4S和5S)的屏幕宽度和iOS版本完全相同,我真的很困惑?

按钮根本不显示。没有编译器警告和没有控制台错误。

更新

在iPhone 5上测试了上面的代码,它运行得很好。这导致相信它必须与iPhone 5S的64位有关吗?

更新2

从方法中删除了所有代码并将其更改为一个非常简单的按钮,如下所示:

         self.saveSearchButton =  [UIButton buttonWithType:UIButtonTypeCustom];
[self.saveSearchButton setTitle:@"Save" forState:UIControlStateNormal];
    [self.saveSearchButton setTintColor:[UIColor blueColor]];
    UIBarButtonItem *saveSearchButton = [[UIBarButtonItem alloc] initWithCustomView:self.saveSearchButton];
    self.navigationItem.rightBarButtonItem = saveSearchButton;

这现在不适用于任何设备或模拟器。

我在这里做错了什么?

更新3 - 解决方案!

是的,所以这是一件简单的事情,引起了所有这些大惊小怪。我将我的UIButtons声明为weak而不是strong - 我的印象是UI元素需要很弱,因为它们常常偏离视线?

我在评论部分的帮助下得出了这个答案。

这也无法解释为什么它在声明为weak时适用于iPhone 4S和iPhone 5。它也适用于声明为weak

的64位模拟器

这是否意味着64位模拟器将用作指南,并且必须在设备上进行实际测试,因为在UIKit测试时模拟器似乎不准确?

我很想知道更多关于此事的信息。

3 个答案:

答案 0 :(得分:6)

问题是[UIButton buttonWithType:UIButtonTypeCustom]没有留下Apple Docs中所述的对象实例。 UIBarButton期待一些实例。 https://developer.apple.com/library/ios/documentation/uikit/reference/UIButton_Class/UIButton/UIButton.html

AppleDocs中说明的解决方案是使用alloc + init构造来制作按钮。

  

buttonWithType:

     

"此方法是用于创建按钮对象的便捷构造函数   具体配置。如果你是UIButton的子类,那么这个方法   不返回子类的实例。如果你想创建一个   在特定子类的实例中,必须分配/初始化按钮   直接"

答案 1 :(得分:2)

@TotumusMaximus您误解了文档的内容。请注意第一部分:

  

如果您继承 UIButton ...

这意味着如果您尝试执行[MyAwesomeButton buttonWithType:UIButtonTypeCustom],则将创建的对象将是UIButton实例,而不是MyAwesomeButton实例。为了获得MyAwesomeButton实例,您需要执行[[MyAwesomeButton alloc] init]。 OP的问题中没有涉及按钮子类,因此这部分文档不适用于此。

答案 2 :(得分:2)

如果你的属性很弱,而你直接为它们分配一个新创建的对象,那么根据ARC的规则,他们应该应该立即被释放并设置为nil,因为没有别的东西拥有强大的参考给他们。在其他设备/模拟器上工作的事实是实施的意外。

现在不再需要为UI元素使用弱属性,因为视图不再在内存压力条件下卸载。如果您仍想使用弱属性,则使用的正确模式是创建本地(强)引用,将其添加到超级视图,然后然后分配给属性 - 此时按钮将拥有一个拥有的参考(超级视图),因此不会被ARC删除:

UIButton *button = [UIButton buttonWithType:whatever];
[self.view addSubview:button];
self.button = button;