UITableViewCell의 iOS7에서 자동 레이아웃 제약 문제
자동 레이아웃 제약 조건을 프로그래밍 방식으로 사용하여 사용자 지정 UITableView 셀을 레이아웃하고 있으며 셀 크기를 올바르게 정의하고 있습니다. tableView:heightForRowAtIndexPath:
iOS6에서 잘 작동 하고 iOS7에서도 잘 보입니다.
하지만 iOS7에서 앱을 실행할 때 콘솔에 표시되는 메시지는 다음과 같습니다.
Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2013-10-02 09:56:44.847 Vente-Exclusive[76306:a0b] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0xac4c5f0 V:|-(15)-[UIImageView:0xac47f50] (Names: '|':UITableViewCellContentView:0xd93e850 )>",
"<NSLayoutConstraint:0xac43620 V:[UIImageView:0xac47f50(62)]>",
"<NSLayoutConstraint:0xac43650 V:[UIImageView:0xac47f50]-(>=0)-[UIView:0xac4d0f0]>",
"<NSLayoutConstraint:0xac43680 V:[UIView:0xac4d0f0(1)]>",
"<NSLayoutConstraint:0xac436b0 V:[UIView:0xac4d0f0]-(0)-| (Names: '|':UITableViewCellContentView:0xd93e850 )>",
"<NSAutoresizingMaskLayoutConstraint:0xac6b120 h=--& v=--& V:[UITableViewCellContentView:0xd93e850(44)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0xac43650 V:[UIImageView:0xac47f50]-(>=0)-[UIView:0xac4d0f0]>
그리고 실제로 그 목록에는 내가 원하지 않는 제약 조건 중 하나가 있습니다.
"<NSAutoresizingMaskLayoutConstraint:0xac6b120 h=--& v=--& V:[UITableViewCellContentView:0xd93e850(44)]>"
의 translatesAutoresizingMaskIntoConstraints
속성 contentView
을 NO =>로 설정할 수 없으므로 전체 셀이 엉망이 될 것입니다.
44는 기본 셀 높이이지만 테이블 뷰 델리게이트에서 사용자 지정 높이를 정의했는데 왜 셀 contentView에이 제약이 있습니까? 원인은 무엇입니까?
iOS6에서는 발생하지 않으며 iOS6 및 iOS7 모두에서 모든 것이 잘 보입니다.
내 코드가 꽤 커서 여기에 게시하지 않겠지 만 필요한 경우 언제든지 pastebin을 요청하십시오.
수행 방법을 지정하려면 셀 초기화에서 다음을 수행하십시오.
- 모든 레이블, 버튼 등을 만듭니다.
- 나는 그들의
translatesAutoresizingMaskIntoConstraints
속성을 NO로 설정했습니다. - 나는 그들을
contentView
세포의 하위보기로 추가 - 나는에 제약을 추가합니다
contentView
나는 이것이 왜 iOS7에서만 발생하는지 이해하는 데 깊은 관심이 있습니다.
나는 또한이 문제가 있었다 .. 그것은 layoutSubviews
호출 될 때까지 contentView의 프레임이 업데이트되지 않는 것처럼 보이지만 {0, 0, 320, 44}
, 제약 조건이 평가 될 때 설정된 contentView의 프레임을 남겨두고 셀의 프레임이 더 일찍 업데이트 됩니다.
contentView를 자세히 살펴보면 autoresizingMask가 더 이상 설정되지 않는 것 같습니다.
뷰를 제한하기 전에 autoresizingMask를 설정하면이 문제를 해결할 수 있습니다.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
if (self)
{
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
[self loadViews];
[self constrainViews];
}
return self;
}
iOS 8 SDK를 사용하는 iOS 7에서 UITableViewCell 및 UICollectionViewCell에 문제가있는 것 같습니다.
다음과 같이 셀을 재사용 할 때 셀의 contentView를 업데이트 할 수 있습니다.
정적 UITableViewController의 경우 :
#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1)
{
cell.contentView.frame = cell.bounds;
cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleTopMargin |UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
}
//your code goes here
return cell;
}
#endif
#endif
Static Table View Controller는 깨지기 쉽고 일부 데이터 소스 또는 deletegate 메서드를 구현하면 쉽게 손상 될 수 있으므로이 코드가 iOS 7에서만 컴파일되고 실행되는지 확인하는 검사가 있습니다.
표준 동적 UITableViewController와 유사합니다.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellID = @"CellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_7_1)
{
cell.contentView.frame = cell.bounds;
cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleTopMargin |UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin;
}
//your code goes here
return cell;
}
이 경우이 메서드를 구현해야하므로 컴파일 추가 검사가 필요하지 않습니다.
The idea is the same for both cases and for UICollectionViewCell, like commented in this thread: Autoresizing issue of UICollectionViewCell contentView's frame in Storyboard prototype cell (Xcode 6, iOS 8 SDK) happens when running on iOS 7 only
As cells are being reused and the height can change based on the content, I think in general it would be better to set the priority of spacings to less than required.
In your case the UIImageView has a spacing of 15 to the top and the bottom view has a spacing of 0 to the bottom. If you set the priority of those constraints to 999 (instead of 1000), the app will not crash, because the constraints are not required.
Once the layoutSubviews method is called, the cell will have the correct height, and the constraints can be satisfied normally.
I still didn't find a good solution for storyboards... Some info also here: https://github.com/Alex311/TableCellWithAutoLayout/commit/bde387b27e33605eeac3465475d2f2ff9775f163#commitcomment-4633188
From what they advice there:
self.contentView.bounds = CGRectMake(0, 0, 99999, 99999);
I've induced my solution:
- right click the storyboard
- Open As -> Source Code
- search for string "44" there
- it's gonna be like
.
<tableView hidden="YES" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" allowsSelection="NO" rowHeight="44" ...
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="ChatMessageCell" id="bCG-aU-ivE" customClass="ChatMessageCell">
<rect key="frame" x="0.0" y="22" width="320" height="44"/>
.
- replace rowHeight="44" with rowHeight="9999" and height="44" with height="9999"
- right click the storyboard
- Open As -> Interface Builder
- run your app and check the output
Just increase the default cell height. Looks like the problem is that the content of the cell is larger than the default (initial) cell size, violating some non-negativity constraints until the cell is resized to its actual size.
Maybe set the view's priority large than 750 and less than 1000 can solve.
"<NSLayoutConstraint:0xac43620 V:[UIImageView:0xac47f50(62)]>",
I had the same problem. My solution based upon others above:
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
// initialize my stuff
[self layoutSubviews]; // avoid debugger warnings regarding constraint conflicts
}
return self;
}
Best, Alessandro
I'v also faced this problem and none of the suggestions helped. In my case I had size selection cell, and it contained collectionView inside (every collectionView cell contained full size image). Now, the cell size heigh was a little bit bigger (60) than the collectionView (50) and images inside it (50). Because of that collectionView view has align bottom to superview constraint with a value of 10. That case me a warning, and the only way to fix that was to make cell height the same as its collectionView.
I ended up by not using UITableViewCell in designer at all... I create there custom view and add it to content view of cell programmatically... With some help categories there is also no code boilerplate...
If it works fine in iOS8,and get the warning in iOS7,you can search the storyboard source code, and find the right tableviewCell, then append the rect attribute after the tableviewCell line. Thanks to kuchumovn.
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" .../>
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
'program story' 카테고리의 다른 글
기대 최대화 기법에 대한 직관적 인 설명은 무엇입니까? (0) | 2020.08.13 |
---|---|
Visual Studio 직접 실행 창을 다시 열려면 어떻게하나요? (0) | 2020.08.13 |
laravel .env 파일에 주석을 추가하는 방법은 무엇입니까? (0) | 2020.08.13 |
C ++에서 C 헤더를 사용할 때 std :: 또는 전역 네임 스페이스의 함수를 사용해야합니까? (0) | 2020.08.13 |
Intellij IDEA에 대해 자동 형식 코드를 활성화하려면 어떻게해야합니까? (0) | 2020.08.13 |