- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我很惭愧地发布这个,但我变得绝望了。
在谈到 AutoLayout 时,我是一个菜鸟。这主要是因为我的应用程序中有将近 60 个不同的屏幕。为什么要改变有效的方法?不管怎样,我不使用 XIBs/NIBs/Storyboards,因为任何时候我需要对应用程序范围的 UI 进行更改,我都必须修复一堆东西。相反,我有自己的一组 UIViewController 子类。其中之一只有一个 UITableView,很像 UITableViewController。我可以在睡梦中制作 UITableViews。
我有一个新屏幕,需要在 TableView 的标题中添加几个按钮。我正在尝试更好地使用 AutoLayout,所以我会尽可能地使用它。没有进一步的叙述,这里有一个非常简短的独立示例。
#import "AppDelegate.h"
@interface TestViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) NSArray *rows;
@end
@implementation TestViewController
- (void) loadView {
UITableView *tv = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds] style:UITableViewStyleGrouped];
[tv setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
[tv setDelegate:self];
[tv setDataSource:self];
[self setView:tv];
UIView *tableHeader = [[UIView alloc] init];
[tableHeader setTranslatesAutoresizingMaskIntoConstraints:NO];
[tv setTableHeaderView:tableHeader];
UIButton *selectProfileButton = [UIButton buttonWithType:UIButtonTypeCustom];
[selectProfileButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[selectProfileButton setShowsTouchWhenHighlighted:YES];
[selectProfileButton setTitle:@"Select Profile..." forState:UIControlStateNormal];
[tableHeader addSubview:selectProfileButton];
UIButton *editProfileButton = [UIButton buttonWithType:UIButtonTypeCustom];
[editProfileButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[editProfileButton setImage:[UIImage imageNamed:@"EditAccessoryIcon"] forState:UIControlStateNormal];
[tableHeader addSubview:editProfileButton];
UIEdgeInsets padding = UIEdgeInsetsMake(5, 10, 5, 5);
// select button in NW corner
[tableHeader addConstraint:[NSLayoutConstraint constraintWithItem:selectProfileButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:tableHeader attribute:NSLayoutAttributeTop multiplier:1.0 constant:padding.top]];
[tableHeader addConstraint:[NSLayoutConstraint constraintWithItem:selectProfileButton attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual
toItem:tableHeader attribute:NSLayoutAttributeLeft multiplier:1.0 constant:padding.left]];
[tableHeader addConstraint:[NSLayoutConstraint constraintWithItem:selectProfileButton attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual
toItem:tableHeader attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-padding.bottom]];
// edit button in NE corner
[tableHeader addConstraint:[NSLayoutConstraint constraintWithItem:editProfileButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
toItem:tableHeader attribute:NSLayoutAttributeTop multiplier:1.0 constant:padding.top]];
[tableHeader addConstraint:[NSLayoutConstraint constraintWithItem:editProfileButton attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual
toItem:tableHeader attribute:NSLayoutAttributeRight multiplier:1.0 constant:-padding.right]];
[tableHeader addConstraint:[NSLayoutConstraint constraintWithItem:editProfileButton attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual
toItem:tableHeader attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-padding.bottom]];
// spacing between buttons
[tableHeader addConstraint:[NSLayoutConstraint constraintWithItem:selectProfileButton attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual
toItem:editProfileButton attribute:NSLayoutAttributeLeft multiplier:1.0 constant:-10.0]];
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [[self rows] count]; }
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
[[cell textLabel] setText:[[self rows] objectAtIndex:[indexPath row]]];
return cell;
}
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
TestViewController *test = [[TestViewController alloc] init];
[test setRows:@[@"1", @"2", @"3"]];
[[self window] setRootViewController:test];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
@end
不幸的是,在运行时我得到了这个:
2014-07-11 13:18:48.502 TestTableHeader[9478:60b] *** Assertion failure in -[UITableView layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2935.137/UIView.m:8794
2014-07-11 13:18:48.505 TestTableHeader[9478:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'
*** First throw call stack:
(
0 CoreFoundation 0x017ed1e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x0156c8e5 objc_exception_throw + 44
2 CoreFoundation 0x017ed048 +[NSException raise:format:arguments:] + 136
3 Foundation 0x0114c4de -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
4 UIKit 0x0029ba38 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 567
5 libobjc.A.dylib 0x0157e82b -[NSObject performSelector:withObject:] + 70
6 QuartzCore 0x03c5845a -[CALayer layoutSublayers] + 148
7 QuartzCore 0x03c4c244 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
8 QuartzCore 0x03c583a5 -[CALayer layoutIfNeeded] + 160
9 UIKit 0x0035dae3 -[UIViewController window:setupWithInterfaceOrientation:] + 304
10 UIKit 0x00273aa7 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 5212
11 UIKit 0x00272646 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 82
12 UIKit 0x00272518 -[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 117
13 UIKit 0x002725a0 -[UIWindow _setRotatableViewOrientation:duration:force:] + 67
14 UIKit 0x0027163a __57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 120
15 UIKit 0x0027159c -[UIWindow _updateToInterfaceOrientation:duration:force:] + 400
16 UIKit 0x002722f3 -[UIWindow setAutorotates:forceUpdateInterfaceOrientation:] + 870
17 UIKit 0x002758e6 -[UIWindow setDelegate:] + 449
18 UIKit 0x0034fb77 -[UIViewController _tryBecomeRootViewControllerInWindow:] + 180
19 UIKit 0x0026b474 -[UIWindow addRootViewControllerViewIfPossible] + 591
20 UIKit 0x0026b5ef -[UIWindow _setHidden:forced:] + 312
21 UIKit 0x0026b86b -[UIWindow _orderFrontWithoutMakingKey] + 49
22 UIKit 0x002763c8 -[UIWindow makeKeyAndVisible] + 65
23 TestTableHeader 0x00002dfa -[AppDelegate application:didFinishLaunchingWithOptions:] + 890
24 UIKit 0x0022614f -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 309
25 UIKit 0x00226aa1 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1810
26 UIKit 0x0022b667 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
27 UIKit 0x0023ff92 -[UIApplication handleEvent:withNewEvent:] + 3517
28 UIKit 0x00240555 -[UIApplication sendEvent:] + 85
29 UIKit 0x0022d250 _UIApplicationHandleEvent + 683
30 GraphicsServices 0x037e2f02 _PurpleEventCallback + 776
31 GraphicsServices 0x037e2a0d PurpleEventCallback + 46
32 CoreFoundation 0x01768ca5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
33 CoreFoundation 0x017689db __CFRunLoopDoSource1 + 523
34 CoreFoundation 0x0179368c __CFRunLoopRun + 2156
35 CoreFoundation 0x017929d3 CFRunLoopRunSpecific + 467
36 CoreFoundation 0x017927eb CFRunLoopRunInMode + 123
37 UIKit 0x0022ad9c -[UIApplication _run] + 840
38 UIKit 0x0022cf9b UIApplicationMain + 1225
39 TestTableHeader 0x00002fed main + 141
40 libdyld.dylib 0x01e34701 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
根据我的阅读,这意味着我缺少一个约束。 UIButtons 有一个固有的大小,所以我只需要设置它们的位置。容器 UIView 将由 UITableView 调整大小,因此无需执行任何操作。 (我什至尝试设置咯咯笑的高度——我没有咯咯笑。)
我哪里搞砸了?
谢谢!
更新了示例代码和堆栈以提供简短的独立示例。
最佳答案
我遇到了同样的问题。我认为这不是由于缺少约束造成的。这是因为 UITableView
显然没有正确处理带有自动布局的页眉/页脚。对我有用的解决方法是使用 systemLayoutSizeFittingSize:
方法设置框架:
//initialize tableHeader, add subviews and constraints
CGSize size = [tableHeader systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
tableHeader.frame = (CGRect){.origin = CGPointZero, .size = size};
self.tableView.tableHeaderView = tableHeader;
请注意,我没有将translatesAutoresizingMaskIntoConstraints
设置为NO
。
此外,您似乎还没有添加所有需要的约束。您只定位按钮,但您的 tableHeader 不知道如何计算其自己的宽度和高度。您可能需要使 selectProfileButton
(或其他按钮)的底部等于 tableHeader
的底部,并在按钮之间添加一个(最小)水平间距。
另外,据我所知,UITableView 会将 tableHeader
的宽度扩展到它自己的宽度,而不管任何约束。
关于ios - 如何使用 AutoLayout 使 UITableView header 的这个简单布局正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24686899/
IO 设备如何知道属于它的内存中的值在memory mapped IO 中发生了变化? ? 例如,假设内存地址 0 专用于保存 VGA 设备的背景颜色。当我们更改 memory[0] 中的值时,VGA
我目前正在开发一个使用Facebook sdk登录(通过FBLoginView)的iOS应用。 一切正常,除了那些拥有较旧版本的facebook的人。 当他们按下“使用Facebook登录”按钮时,他
假设我有: this - is an - example - with some - dashesNSRange将使用`rangeOfString:@“-”拾取“-”的第一个实例,但是如果我只想要最后
Card.io SDK提供以下详细信息: 卡号,有效期,月份,年份,CVV和邮政编码。 如何从此SDK获取国家名称。 - (void)userDidProvideCreditCardInfo:(Car
iOS 应用程序如何从网络服务下载图片并在安装过程中将它们安装到用户的 iOS 设备上?可能吗? 最佳答案 您无法控制应用在用户设备上的安装,因此无法在安装过程中下载其他数据。 只需在安装后首次启动应
我曾经开发过一款企业版 iOS 产品,我们公司曾将其出售给大型企业,供他们的员工使用。 该应用程序通过 AppStore 提供,企业用户获得了公司特定的配置文件(包含应用程序配置文件)以启用他们有权使
我正在尝试将 Card.io SDK 集成到我的 iOS 应用程序中。我想为 CardIO ui 做一个简单的本地化,如更改取消按钮标题或“在此保留信用卡”提示文本。 我在 github 上找到了这个
我正在使用 CardIOView 和 CardIOViewDelegate 类,没有可以设置为 YES 的 BOOL 来扫描 collectCardholderName。我可以看到它在 CardIOP
我有一个集成了通话工具包的 voip 应用程序。每次我从我的 voip 应用程序调用时,都会在 native 电话应用程序中创建一个新的最近通话记录。我在 voip 应用程序中也有自定义联系人(电话应
iOS 应用程序如何知道应用程序打开时屏幕上是否已经有键盘?应用程序运行后,它可以接收键盘显示/隐藏通知。但是,如果应用程序在分屏模式下作为辅助应用程序打开,而主应用程序已经显示键盘,则辅助应用程序不
我在模拟器中收到以下错误: ImageIO: CGImageReadSessionGetCachedImageBlockData *** CGImageReadSessionGetCachedIm
如 Apple 文档所示,可以通过 EAAccessory Framework 与经过认证的配件(由 Apple 认证)进行通信。但是我有点困惑,因为一些帖子告诉我它也可以通过 CoreBluetoo
尽管现在的调试器已经很不错了,但有时找出应用程序中正在发生的事情的最好方法仍然是古老的 NSLog。当您连接到计算机时,这样做很容易; Xcode 会帮助弹出日志查看器面板,然后就可以了。当您不在办公
在我的 iOS 应用程序中,我定义了一些兴趣点。其中一些有一个 Kontakt.io 信标的名称,它绑定(bind)到一个特定的 PoI(我的意思是通常贴在信标标签上的名称)。现在我想在附近发现信标,
我正在为警报提示创建一个 trigger.io 插件。尝试从警报提示返回数据。这是我的代码: // Prompt + (void)show_prompt:(ForgeTask*)task{
您好,我是 Apple iOS 的新手。我阅读并搜索了很多关于推送通知的文章,但我没有发现任何关于 APNS 从 io4 到 ios 6 的新更新的信息。任何人都可以向我提供 APNS 如何在 ios
UITabBar 的高度似乎在 iOS 7 和 8/9/10/11 之间发生了变化。我发布这个问题是为了让其他人轻松找到答案。 那么:在 iPhone 和 iPad 上的 iOS 8/9/10/11
我想我可以针对不同的 iOS 版本使用不同的 Storyboard。 由于 UI 的差异,我将创建下一个 Storyboard: Main_iPhone.storyboard Main_iPad.st
我正在写一些东西,我将使用设备的 iTunes 库中的一部分音轨来覆盖 2 个视频的组合,例如: AVMutableComposition* mixComposition = [[AVMutableC
我创建了一个简单的 iOS 程序,可以顺利编译并在 iPad 模拟器上运行良好。当我告诉 XCode 4 使用我连接的 iPad 设备时,无法编译相同的程序。问题似乎是当我尝试使用附加的 iPad 时
我是一名优秀的程序员,十分优秀!