【发布时间】:2014-02-18 23:34:42
【问题描述】:
所以我有一个在 IB 中设置的视图,我需要以编程方式更改框架。出于某种原因,在我设置它之后,框架不断恢复到它的 IB 位置。我将 NSView 子类化并在-setFrame:(NSRect)frameRect 方法中记录了框架,看起来-setFrame: 被调用了两次——一次是在我设置它时(它记录新值),一次是在它恢复时(它记录IB值)。我似乎无法提取问题的根源,因为在某些情况下(例如,如果我有一个专门用于设置它的 NSButton 或有一个计时器设置框架)它可以完美地工作,但是如果我有 -setFrame: 调用- 与我的其他代码一致,它总是会恢复。
编辑:
这是一个显示问题的简单示例(IB中的原始帧是{{20, 118}, {48, 48}}):
AppDelegate.m:
#import "AppDelegate.h"
@implementation AppDelegate
- (void)awakeFromNib{
[self.button setFrame:NSMakeRect(50, 10, 100, 100)];
}
@end
日志:
2014-02-18 18:01:40.206 WHS-ChangingFrameTest[15210:303] Frame: {{50, 10}, {100, 100}}
2014-02-18 18:01:41.223 WHS-ChangingFrameTest[15210:303] Frame: {{20, 118}, {48, 48}}
编辑#2:
在我编辑框架时调用堆栈(来自原始应用):
0 MyApp 0x000000010000203c -[FrameLogProgressIndicator setFrame:] + 284
1 MyApp 0x000000010001c994 -[SubjectViewController updateTableViewHeight] + 1284
2 MyApp 0x000000010001c468 -[SubjectViewController updateUI] + 4664
3 MyApp 0x0000000100012f2f -[TabMenuViewController updateDisplayingBlock:] + 975
4 MyApp 0x0000000100010c59 -[TabMenuViewController switchBlockFromDaySchedulePopover:] + 873
5 AppKit 0x00007fff82eea959 -[NSApplication sendAction:to:from:] + 342
6 AppKit 0x00007fff82eea7b7 -[NSControl sendAction:to:] + 85
7 AppKit 0x00007fff82eea6eb -[NSCell _sendActionFrom:] + 138
8 AppKit 0x00007fff82ee8bd3 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 1855
9 AppKit 0x00007fff82ee8421 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 504
10 AppKit 0x00007fff82ee7b9c -[NSControl mouseDown:] + 820
11 AppKit 0x00007fff82edf50e -[NSWindow sendEvent:] + 6853
12 AppKit 0x00007fff82edb644 -[NSApplication sendEvent:] + 5761
13 AppKit 0x00007fff82df121a -[NSApplication run] + 636
14 AppKit 0x00007fff82d95bd6 NSApplicationMain + 869
15 MyApp 0x00000001000020a2 main + 34
16 libdyld.dylib 0x00007fff8152a7e1 start + 0
17 ??? 0x0000000000000003 0x0 + 3
)
从帧恢复时调用堆栈:
0 MyApp 0x000000010000203c -[FrameLogProgressIndicator setFrame:] + 284
1 AppKit 0x00007fff82e21e77 -[NSView resizeWithOldSuperviewSize:] + 659
2 AppKit 0x00007fff82e21307 -[NSView resizeSubviewsWithOldSize:] + 318
3 AppKit 0x00007fff82f08399 NSViewLevelLayout + 44
4 AppKit 0x00007fff82f07e65 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 112
5 CoreFoundation 0x00007fff84b524a6 __NSArrayEnumerate + 582
6 AppKit 0x00007fff82f07fc6 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
7 CoreFoundation 0x00007fff84b524a6 __NSArrayEnumerate + 582
8 AppKit 0x00007fff82f07fc6 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
9 CoreFoundation 0x00007fff84b524a6 __NSArrayEnumerate + 582
10 AppKit 0x00007fff82f07fc6 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
11 CoreFoundation 0x00007fff84b524a6 __NSArrayEnumerate + 582
12 AppKit 0x00007fff82f07fc6 -[NSView _layoutSubtreeHeedingRecursionGuard:] + 465
13 AppKit 0x00007fff82f07cfe -[NSView layoutSubtreeIfNeeded] + 615
14 AppKit 0x00007fff82f034ac -[NSWindow(NSConstraintBasedLayout) layoutIfNeeded] + 201
15 AppKit 0x00007fff82dfd0a8 _handleWindowNeedsDisplayOrLayoutOrUpdateConstraints + 446
16 AppKit 0x00007fff833c8901 __83-[NSWindow _postWindowNeedsDisplayOrLayoutOrUpdateConstraintsUnlessPostingDisabled]_block_invoke_01208 + 46
17 CoreFoundation 0x00007fff84b20417 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
18 CoreFoundation 0x00007fff84b20381 __CFRunLoopDoObservers + 369
19 CoreFoundation 0x00007fff84afb7b8 __CFRunLoopRun + 728
20 CoreFoundation 0x00007fff84afb0e2 CFRunLoopRunSpecific + 290
21 HIToolbox 0x00007fff8231aeb4 RunCurrentEventLoopInMode + 209
22 HIToolbox 0x00007fff8231ab94 ReceiveNextEventCommon + 166
23 HIToolbox 0x00007fff8231aae3 BlockUntilNextEventMatchingListInMode + 62
24 AppKit 0x00007fff82dfa533 _DPSNextEvent + 685
25 AppKit 0x00007fff82df9df2 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 128
26 AppKit 0x00007fff82df11a3 -[NSApplication run] + 517
27 AppKit 0x00007fff82d95bd6 NSApplicationMain + 869
28 MyApp 0x00000001000020a2 main + 34
29 libdyld.dylib 0x00007fff8152a7e1 start + 0
30 ??? 0x0000000000000003 0x0 + 3
)
如果我需要发布堆栈中使用的方法中的代码以使其有用,请告诉我。 (对不起,我以前从未真正处理过这些东西)
【问题讨论】:
-
请发布一个调用堆栈,其中 setFrame 被错误数据调用
-
可能你从错误的地方调用你的帧更新。但是您没有向我提供其他信息。所以我帮不了你。
-
改变框架是什么意思?是大小,位置? -1
-
@Avt 我一直在尝试以一种不受我正在处理的问题的大程序的约束的方式重新创建这种情况。我想来自较大程序的所有调用都将无济于事,但正如我所说,我无法找出问题的根源。当我可以将其简化为更简单的内容时,我会更新。
-
您可能在视图上设置了自动布局约束,它们会自动布局视图。但是,是的,显示调用堆栈会确认。在您的日志语句中包含
[NSThread callStackSymbols]。
标签: objective-c cocoa interface-builder frame nsview