UITableViewCell이 빠르게 뒤로 스 와이프해도 선택 해제되지 않습니다.
이제 세 가지 앱을 iOS 7로 업데이트했지만 세 앱 모두 코드를 공유하지 않음에도 불구하고 사용자가 뒤로 버튼을 누르는 대신 내비게이션 컨트롤러에서 빠르게 돌아갈 수있는 문제가 있습니다. , 셀은 선택된 상태로 유지됩니다.
세 앱의 경우 하나는 프로그래밍 방식으로 만든 사용자 지정 셀을 사용하고 다른 하나는 스토리 보드에서 만든 사용자 지정 셀을 사용하고 세 번째 앱은 스토리 보드에서도 UITableView의 매우 기본적인 하위 클래스에있는 기본 셀을 사용합니다. 세 가지 경우 모두 셀은 스스로 선택을 취소하지 않습니다. 사용자가 천천히 스 와이프하거나 뒤로 버튼을 누르면 정상적으로 선택 해제됩니다.
이것은 내 iOS 7 앱에서만 발생하며, Apple의 자체 앱 및 iOS 7 용으로 업그레이드 된 타사 앱은 모두 정상적으로 작동하는 것 같습니다 (셀 선택 해제 속도에 약간의 차이가 있음).
내가 뭘 잘못하고있는 게 분명한데 뭔지 모르겠어?
나는 지금 같은 문제를 다루고 있습니다. Apple 의 UICatalog 샘플은 더러운 솔루션을 가져 오는 것 같습니다.
정말 저를 전혀 행복하게하지 않습니다. 앞에서 언급했듯이 [self.tableView deselectRowAtIndexPath:tableSelection animated:NO];
현재 선택된 행을 선택 취소하는 데 사용 합니다.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// this UIViewController is about to re-appear, make sure we remove the current selection in our table view
NSIndexPath *tableSelection = [self.tableView indexPathForSelectedRow];
[self.tableView deselectRowAtIndexPath:tableSelection animated:NO];
// some over view controller could have changed our nav bar tint color, so reset it here
self.navigationController.navigationBar.tintColor = [UIColor darkGrayColor];
}
샘플 코드는 IOS 7 iOS 8 iOS 9 iOS 10 지원
나를 혼란스럽게하는 것은 UITableViewController Class Reference입니다 .
테이블 뷰가 처음로드 될 때 나타나려고 할 때 테이블 뷰 컨트롤러는 테이블 뷰의 데이터를 다시로드합니다. 또한 테이블 뷰가 표시 될 때마다 선택 항목 (요청에 따라 애니메이션 포함 또는 제외)을 지 웁니다.
UITableViewController
클래스는 슈퍼 클래스의 방법이 구현viewWillAppear:
.clearsSelectionOnViewWillAppear
속성 의 값을 변경하여이 동작을 비활성화 할 수 있습니다 .
이것이 내가 기대하는 동작과 정확히 일치하지만 작동하지 않는 것 같습니다. 당신도 나도 마찬가지입니다. 우리는 정말로 "더러운"해결책을 사용해야하고 우리 스스로해야합니다.
이것은 나를 위해 가장 잘 작동했습니다.
- (void)viewDidLoad {
[super viewDidLoad];
self.clearsSelectionOnViewWillAppear = NO;
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated];
}
천천히 뒤로 스 와이프하는 동안 훨씬 더 나은 선택 해제 페이딩을 얻었습니다.
Fabio의 대답은 잘 작동하지만 사용자가 약간 스 와이프 한 다음 마음이 바뀌면 올바른 모양을 제공하지 않습니다. 이 경우를 올바르게하려면 선택한 인덱스 경로를 저장하고 필요할 때 재설정해야합니다.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.savedSelectedIndexPath = nil;
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if (self.savedSelectedIndexPath) {
[self.tableView selectRowAtIndexPath:self.savedSelectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.savedSelectedIndexPath = self.tableView.indexPathForSelectedRow;
if (self.savedSelectedIndexPath) {
[self.tableView deselectRowAtIndexPath:self.savedSelectedIndexPath animated:YES];
}
}
UITableViewController를 사용하는 경우 기본 제공 지우기를 비활성화해야합니다.
self.clearsSelectionOnViewWillAppear = NO;
savedSelectedIndexPath에 대한 속성을 추가합니다.
@property(strong, nonatomic) NSIndexPath *savedSelectedIndexPath;
몇 가지 다른 클래스에서이 작업을 수행해야하는 경우 헬퍼에서 분할하는 것이 좋습니다. 예를 들어이 요점에서 한 것처럼 https://gist.github.com/rhult/46ee6c4e8a862a8e66d4
이 솔루션은 전환 조정자와 함께 행 선택 취소를 애니메이션 (사용자 주도 VC 해제의 경우)하고 사용자가 전환을 취소하면 선택을 다시 적용합니다. Swift의 Caleb Davenport 의 솔루션에서 수정되었습니다 . iOS 9에서만 테스트되었습니다. 사용자 주도 (스 와이프) 전환과 이전 스타일의 "뒤로"버튼 탭 모두에서 작동하는 것으로 테스트되었습니다.
에서 UITableViewController
서브 클래스 :
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Workaround. clearsSelectionOnViewWillAppear is unreliable for user-driven (swipe) VC dismiss
NSIndexPath *indexPath = self.tableView.indexPathForSelectedRow;
if (indexPath && self.transitionCoordinator) {
[self.transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
[self.tableView deselectRowAtIndexPath:indexPath animated:animated];
} completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
if ([context isCancelled]) {
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
}];
}
}
오늘 직접이 문제를 경험 한 후, 이것이 UITableView에서 상당히 잘 알려진 문제라는 것을 알게되었습니다. 대화 형 탐색 전환에 대한 지원이 약간 손상되었습니다. Castro 뒤에있는 사람들은 이에 대한 훌륭한 분석과 해결책을 게시했습니다 : http://blog.supertop.co/post/80781694515/viewmightappear
취소 된 전환도 고려하는 솔루션을 사용하기로 결정했습니다.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSIndexPath *selectedRowIndexPath = [self.tableView indexPathForSelectedRow];
if (selectedRowIndexPath) {
[self.tableView deselectRowAtIndexPath:selectedRowIndexPath animated:YES];
[[self transitionCoordinator] notifyWhenInteractionEndsUsingBlock:^(id<UIViewControllerTransitionCoordinatorContext> context) {
if ([context isCancelled]) {
[self.tableView selectRowAtIndexPath:selectedRowIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
}];
}
}
설정을 시도 할 수 있습니다.
self.clearsSelectionOnViewWillAppear = YES;
UITableViewController 또는
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:NO];
viewWillAppear에서 [super viewWillAppear : animated]를 호출하기 전에; UItableView가 UITableViewController 내에 있지 않은 경우 수동으로 셀을 선택 취소해야합니다.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
나는 사용하고있다
[tableView deselectRowAtIndexPath:indexPath animated:YES];
방법의 끝에서
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
이렇게 :
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//doing something according to selected cell...
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
간단한 Swift 3/4 답변 :
override func viewWillAppear(_ animated: Bool) {
if tableView.indexPathForSelectedRow != nil {
self.tableView.deselectRow(at: tableView.indexPathForSelectedRow! as IndexPath, animated: true)
}
}
사용하다
[tableView deselectRowAtIndexPath:indexPath animated:YES];
코드 입력
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method
이 문제에 대한 매우 간단한 해결책을 찾았습니다. 기본 동작이 제대로 작동하도록합니다. deselectRowAtIndexPath
결과적인 시각 효과가 약간 다르기 때문에 관련 솔루션에 만족하지 못했습니다 .
이 이상한 동작을 방지하기 위해해야 할 일은 뷰가 표시 될 때 테이블을 다시로드하는 것입니다.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.tableView reloadData];
}
Swift 3의 Codestage 답변notifyWhenInteractionEnds
은 더 이상 사용되지 않습니다.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
if let indexPath = self.tableView.indexPathForSelectedRow {
self.tableView.deselectRow(at: indexPath, animated: true)
self.transitionCoordinator?.notifyWhenInteractionChanges { (context) in
if context.isCancelled {
self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
}
}
}
}
You are probably not calling the super view's viewWillAppear method ([super viewWillAppear:animated];). When you do this and the UITableViewController's parameter clearsSelectionOnViewWillAppear is YES then the cells will be deselected on viewWillAppear.
Based on Rhult's code, I made a few changes.
This implementation allow user to cancel swipe back and still keep selected for future swipe back deselect animation
@property(strong, nonatomic) NSIndexPath *savedSelectedIndexPath;
- (void)viewDidLoad {
[super viewDidLoad];
self.clearsSelectionOnViewWillAppear = NO;
}
-(void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.savedSelectedIndexPath = nil;
}
-(void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.savedSelectedIndexPath && ![self.tableView indexPathForSelectedRow]) {
[self.tableView selectRowAtIndexPath:self.savedSelectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
} else {
self.savedSelectedIndexPath = [self.tableView indexPathForSelectedRow];
}
}
Rhult's solution works perfectly on iOS 9.2. This is the implementation in Swift:
Declare a variable in your MasterViewController
to save the IndexPath:
var savedSelectedIndexPath: NSIndexPath?
Then you can put the code in an extension for clarity:
extension MasterViewController {
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.savedSelectedIndexPath = nil
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if let indexPath = self.savedSelectedIndexPath {
self.tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: .None)
}
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.savedSelectedIndexPath = tableView.indexPathForSelectedRow
if let indexPath = self.savedSelectedIndexPath {
self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
}
}
Codestage provided by far the best looking answer, so I decided to convert it into Swift 2.
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
let selectedRowIndexPath = self.tableView.indexPathForSelectedRow
if ((selectedRowIndexPath) != nil) {
self.tableView.deselectRowAtIndexPath(selectedRowIndexPath!, animated: true)
self.transitionCoordinator()?.notifyWhenInteractionEndsUsingBlock({ context in
if (context.isCancelled()) {
self.tableView.selectRowAtIndexPath(selectedRowIndexPath, animated: false, scrollPosition: UITableViewScrollPosition.None)
}
})
}
}
For swift
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
guard let indexPath = tableView.indexPathForSelectedRow else{
return
}
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
'code' 카테고리의 다른 글
android-프로그래밍 방식으로 LayoutParams 설정 (0) | 2020.12.07 |
---|---|
Ace Cloud 9 편집기에서 콘텐츠 높이 자동 조정 (0) | 2020.12.07 |
gradlew 또는 gradle로 종속성 트리를 볼 수 없습니다. (0) | 2020.12.07 |
Composer가 버전 X와 버전 Y 사이의 PHP 버전을 요구하도록합니다. (0) | 2020.12.07 |
ActiveRecord가 클래스를 다시로드하도록하려면 어떻게해야합니까? (0) | 2020.12.07 |