UISearchDisplayController가 탐색 모음을 숨기지 못하도록 방지
사용자가 UISearchDisplayController
의 검색 표시 줄 편집을 시작할 때마다 검색 컨트롤러가 활성화되고 검색 테이블보기를 표시하는 동안보기의 탐색 표시 줄을 숨 깁니다. UISearchDisplayController
에서 다시 구현하지 않고 탐색 모음을 숨기는 것을 방지 할 수 있습니까?
UISearchController
iOS 8에 도입 된 새 클래스 hidesNavigationBarDuringPresentation
에는 탐색 모음을 계속 표시하려면 false로 설정할 수 있는 속성 이 있습니다 (기본적으로 숨겨져 있음).
방금 UISearchDisplayController로 약간 디버깅 한 결과 UINavigationController에서 개인 메서드를 호출하여 탐색 모음을 숨기는 것을 발견했습니다. 이것은 -setActive : animated :에서 발생합니다. UISearchDisplayController를 하위 클래스로 만들고이 메서드를 다음 코드로 덮어 쓰면 navigationBar가 이미 숨겨져있는 것처럼 위장하여 숨겨지는 것을 방지 할 수 있습니다.
- (void)setActive:(BOOL)visible animated:(BOOL)animated;
{
if(self.active == visible) return;
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
if (visible) {
[self.searchBar becomeFirstResponder];
} else {
[self.searchBar resignFirstResponder];
}
}
이것이 당신에게 효과가 있는지 알려주십시오. 나는 또한 이것이 향후 iOS 버전에서 깨지지 않기를 바랍니다. iOS 4.0에서만 테스트되었습니다.
가장 간단한 솔루션이며 해킹이 없습니다.
@interface MySearchDisplayController : UISearchDisplayController
@end
@implementation MySearchDisplayController
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
[super setActive: visible animated: animated];
[self.searchContentsController.navigationController setNavigationBarHidden: NO animated: NO];
}
@end
위의 답변은 저에게 적합하지 않았습니다. 내 해결책은 UISearchDisplayController를 속여 UINavigationController가 없다고 생각하는 것입니다.
뷰 컨트롤러에서 다음 메서드를 추가하십시오.
- (UINavigationController *)navigationController {
return nil;
}
정말 나쁜 생각처럼 보였음에도 불구하고 이것은 나에게 부적합한 부작용이 없었습니다. 네비게이션 컨트롤러에 가야한다면 [super navigationController]
.
iOS 8.0부터 UISearchController
의 self.searchController.hidesNavigationBarDuringPresentation
속성을 false 로 설정하여 동일한 동작을 수행 할 수 있습니다 .
Swift의 코드는 다음과 같습니다.
searchController.hidesNavigationBarDuringPresentation = false
UISearchDisplayController를 서브 클래 싱하지 않고 다른 방법으로 시도했습니다. UISearchDisplayController에 대한 대리자를 설정 한 UIViewController 클래스에서 searchDisplayControllerDidBeginSearch를 구현하고 사용을 추가하십시오.
[self.navigationController setNavigationBarHidden:NO animated:YES];
나를 위해 속임수를 썼습니다.
나는 약간 다른 문제를 해결하면서 이것을 만났습니다. UISearchDisplayController를 사용하는 동안 검색 막대가 탐색 막대 (아래가 아님) 에 있기 를 원합니다 .
탐색 표시 줄에 검색 표시 줄을 배치하는 것은 어렵지 않습니다 ( UISearchBar 및 UINavigationItem 참조 ). 그러나 UISearchDisplayController는 검색 표시 줄이 항상 내비게이션 표시 줄 아래에 있다고 가정하고 (여기에 설명 된대로) 검색을 입력 할 때 내비게이션 표시 줄을 숨기도록 고집하므로 상황이 끔찍해 보입니다. 또한 UISearchDisplayController는 검색 창을 평소보다 더 밝게합니다.
해결책을 찾았습니다. 트릭은 (반 직관적으로) UISearchDisplayController가 UISearchBar를 전혀 제어하지 못하도록하는 것입니다. xibs를 사용하는 경우 이는 검색 창 인스턴스를 삭제하거나 적어도 콘센트를 분리하는 것을 의미합니다. 그런 다음 고유 한 UISearchBar를 만듭니다.
- (void)viewDidLoad
{
[super viewDidLoad];
UISearchBar *searchBar = [[[UISearchBar alloc] init] autorelease];
[searchBar sizeToFit]; // standard size
searchBar.delegate = self;
// Add search bar to navigation bar
self.navigationItem.titleView = searchBar;
}
You will need to manually activate the search display controller when the user taps the search bar (in -searchBarShouldBeginEditing:
) and manually dismiss the search bar when the user ends searching (in -searchDisplayControllerWillEndSearch:
).
#pragma mark <UISearchBarDelegate>
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
// Manually activate search mode
// Use animated=NO so we'll be able to immediately un-hide it again
[self.searchDisplayController setActive:YES animated:NO];
// Hand over control to UISearchDisplayController during the search
searchBar.delegate = (id <UISearchBarDelegate>)self.searchDisplayController;
return YES;
}
#pragma mark <UISearchDisplayDelegate>
- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController
*)controller {
// Un-hide the navigation bar that UISearchDisplayController hid
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
- (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController
*)controller {
UISearchBar *searchBar = (UISearchBar *)self.navigationItem.titleView;
// Manually resign search mode
[searchBar resignFirstResponder];
// Take back control of the search bar
searchBar.delegate = self;
}
Really nice solution, but it was crashing my app under iOS6. I had to make the following modification to get it work.
@implementation ICSearchDisplayController
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
if (visible == YES) {
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
} else {
[super setActive:NO animated:NO];
}
}
This seem to solve it for me. Tested in both iOS5/6.1. No visual issues that I could see.
- (void)viewDidAppear
{
[super viewDidAppear];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillAppear:) name:UIKeyboardWillShowNotification object:nil];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)keyboardWillAppear:(NSNotification *)notification
{
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
-(void)viewDidLayoutSubviews{
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
iOS 7 screws things up a bit... for me this worked perfectly:
/**
* Overwrite the `setActive:animated:` method to make sure the UINavigationBar
* does not get hidden and the SearchBar does not add space for the statusbar height.
*
* @param visible `YES` to display the search interface if it is not already displayed; NO to hide the search interface if it is currently displayed.
* @param animated `YES` to use animation for a change in visible state, otherwise NO.
*/
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
The reason for show/hide the statusbar
I think the best solution is to implement the UISearchDisplayController yourself.
It's not that difficult. You only need to implement UISearchBarDelegate for your UIViewController and include a UITableView to display your search results.
@Pavel's works perfectly well. However, I was trying to get this into a UIPopoverController and the text in the field gets pushed slightly when the search bar's text field becomes the first responder, and that looks a bit ugly, so I fixed it by calling the super
method with animated
set to NO
.
As jrc pointed out "unhook UISearchDisplayController from controlling any UISearchBar" seems to work for me. If I pass nil as a parameter when creating UISearchDisplayController the navigation bar stays visible at all times:
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:nil contentsController:self];
I was adding custom navigation bar on my ViewController which was getting hidden on search, a quick but not so good fix was
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
[self.view addSubview:_navBar];
}
_navBar is UINavigationBar added programmatically, doing this helped me navigation bar from hiding.
Just wanted to add to stigi answer. When you cancel search and start search again - search results table won't be react to touches so you need to add next line
self.searchResultsTableView.alpha = 1;
So updated code looks next way
- (void)setActive:(BOOL)visible animated:(BOOL)animated;
{
if(self.active == visible) return;
if (visible) {
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
self.searchResultsTableView.alpha = 1;
[self.searchBar becomeFirstResponder];
} else {
[super setActive:visible animated:animated];
[self.searchBar resignFirstResponder];
}
}
'Programing' 카테고리의 다른 글
탐색 창 헤더에서 TextView의 텍스트를 변경하는 방법은 무엇입니까? (0) | 2020.11.16 |
---|---|
urllib와 같은 mock / stub 파이썬 모듈은 어떻게 할 수 있습니까? (0) | 2020.11.16 |
vim regex는 여러 연속 공백을 하나의 공백으로 만 바꿉니다. (0) | 2020.11.16 |
jQuery UI datepicker에서 오늘 날짜를 기본 날짜로 설정 (0) | 2020.11.16 |
$ a + ++ $ a == 2 인 이유는 무엇입니까? (0) | 2020.11.16 |