iPhone : 기본적으로 UITableView 검색 창 패키지
Interface Builder를 사용하여 테이블보기를 만들 예정 여기에 라이브러리의 검색 표시 줄과 검색 컨트롤러를 추가하여 검색 기능을 추가했습니다. 그러나 IB는 뷰가 처음 표시 될 때 화면 상단에 막대가 표시 설정했습니다.
검색 창을 기본적으로 숨기지 만 테이블보기로 스크롤 할 수있는 방법을 알고 싶습니다 (예는 Apple의 메일 애플리케이션 참조). 나는 전화 해봤 scrollRectToVisible:animated:
에서 viewDidLoad
테이블 뷰를 아래로 스크롤 할 수 있습니다 아무 소용. 기본적으로 검색 창을 숨기는 선호하는 방법은 무엇입니까?
먼저 UITableView의 tableHeaderView에 UISearchBar를 추가하여 테이블의 내용과 함께 스크롤되고 뷰 상단에 고정하지 마십시오.
검색 표시 줄은 테이블보기에서 행으로 계산되지 않은 테이블보기의 상단을 첫 번째 행으로 스크롤하면 검색 표시 줄이 '숨겨집니다'.
[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
또는 Swift에서 :
yourTableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: false)
데이터를 포함하기 전에 tableview를 스크롤 scrollToRowAtIndexPath
하지 않고 (주어진 indexPath가 유효한 행을 가리 키지 않는 경우 (즉, tableview가 비어있는 경우) 예외가 발생 함).
UITableView의 하위보기로 UISearchBar를 추가하지 않습니다. 필요하지 않습니다.
UITableView에는 이에 이에 대한 tableHeaderView 속성이 있습니다.
- (void) viewDidLoad {
[super viewDidLoad];
self.searchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)] autorelease];
self.searchBar.showsCancelButton = YES;
self.searchBar.delegate = self;
self.tableView.tableHeaderView = self.searchBar;
}
기본적으로보고 싶지 않은 경우 :
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView setContentOffset:CGPointMake(0, 44)];
}
다시 숨길 수있는 취소 버튼도 있습니다 .... (키보드 제거)
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
[self.tableView setContentOffset:CGPointMake(0, 44) animated:YES];
[self.searchBar resignFirstResponder];
}
contentOffset은 Tim과 Joe D 'Andrea의 의견에 언급 검색 창을 숨기는 애니메이션을 추가하여 확장합니다. 검색 창이 사라지는 것은 예상치 못한 일이라는 것을 알았습니다.
iOS 4.0 이상을 대상으로하는 사람들을위한 약간의 업데이트는 다음과 같습니다.
[UIView animateWithDuration:0.4 animations:^{
self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height);
} completion:nil];
이전 답변 :
[UIView beginAnimations:@"hidesearchbar" context:nil];
[UIView setAnimationDuration:0.4];
[UIView setAnimationBeginsFromCurrentState:YES];
self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height);
[UIView commitAnimations];
이 솔루션에 대한 많은 답변이 나에게 잘 맞는 것은 없습니다.
이것은 완벽하게 작동합니다. 애니메이션이 수행됩니다.-viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.contentOffset = CGPointMake(0, self.searchBar.frame.size.height - self.tableView.contentOffset.y);
}
노트 :
코드는 searchBar
@property
검색 창에이 존재하는 가정합니다 . 않은 경우 오는가 self.searchDisplayController.searchBar
대신 사용할 수 있습니다.
Swift 3 이상
나는 이걸했다 :
주문하십시오 var
:
var searchController = UISearchController()
그리고 viewDidLoad()
방법
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.hidesNavigationBarDuringPresentation = false
searchController.dimsBackgroundDuringPresentation = true
searchController.searchBar.placeholder = NSLocalizedString("Search", comment: "")
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar
tableView.contentOffset = CGPoint(x: 0, y: searchController.searchBar.frame.size.height)
내 목표는 뷰 컨트롤러가로드 될 때 스토리 보드에서 일반 TableView 스타일의 tableHeaderView에 추가 된 검색 창을 숨기고 사용자가 UITableView 상단에서 아래로 스크롤하면 막대를 표시하는 것이 었습니다. 그래서 저는 Swift를 사용 하고 확장 기능을 추가했습니다.
extension UITableView {
func hideSearchBar() {
if let bar = self.tableHeaderView as? UISearchBar {
let height = CGRectGetHeight(bar.frame)
let offset = self.contentOffset.y
if offset < height {
self.contentOffset = CGPointMake(0, height)
}
}
}
}
에 있는 viewDidLoad () 단지 전화 :
self.tableView.hideSearchBar()
위의 어느 것도 나를 위해 일하지 누군가가 같은 문제를 일하지 않을 수도 있습니다.
나는 한로 searchBar
설정 tableHeaderView
iOS7 에에 그룹화 된 테이블에. 에서 viewDidLoad
내가 가진 tableView.contentOffset = CGPointMake(0, 44);
유지하기 위해 searchBar
보기 처음에 "숨겨진". 가 아래 user- searchBar
로 스크롤하면-display됩니다.
목표 : 취소 버튼 탭시 searchBar 패키지
에 searchBarCancelButtonClicked(searchBar: UISearchBar!)
이것은 작동하지 않습니다. [yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
tableView가 너무 많이 스크롤하여 toolBar 20 행이 생겼습니다.
작동하지 않음 : tableView.ContentOffset = CGPointMake(0, 44)
- 일도 일어나지 아무 않습니다.
작동하지 않음 : tableView.ContentOffset = CGPointMake(0, searchBar.frame.size.height)
- 일도 일어나지 아무 않습니다.
이것은 작동하지 않습니다. tableView.setContentOffset(CGPointMake(0, 44), animated: true);
다시 tableView가 너무 많이 스크롤하여 toolBar 0 행이 생겼습니다.
이것은 부분적으로 작동 tableView.setContentOffset(CGPointMake(0, 0)
했지만 titleForHeaderInSection
toolBar 뒤에서 진행되었습니다.
이 작동 : tableView.setContentOffset(CGPointMake(0, -20)
위치이지 않은 것처럼 보이지만 -20 만 올바른 위치로 이동했습니다.
iOS 가이 상황에서 자동으로 삽입을 조정하기 때문에 tableView를 채우기에 충분한 행이 없을 때 iOS 8에서 모든 기존 솔루션이 작동하지 않습니다. (충분한 행이 있으면 답변이 좋습니다)
이 문제에 6 개의 시간을 사용할 수있는 후 최종이 솔루션을 얻었습니다.
간단히 말해, 셀이 충분하지 않은 경우 빈 셀을 tableView에 삽입해야 할 때 tableView의 콘텐츠 크기가 충분히 커서 iOS가 삽입을 조정하지 않습니다.
Swift에서 한 방법은 다음과 가변합니다.
1.) 변수 minimumCellNum
를 클래스 속성으로 선언
var minimumCellNum: Int?
(2))을 계산 minimumCellNum
하고 집합 tableView.contentOffset
에viewWillAppear
let screenHeight = Int(UIScreen.mainScreen().bounds.height)
// 101 = Height of Status Bar(20) + Height of Navigation Bar(44) + Height of Tab Bar(49)
// you may need to subtract the height of other custom views from the screenHeight. For example, the height of your section headers.
self.minimumCellNum = (screenHeight - 103 - heightOfOtherCustomView) / heightOfYourCell
self.tableView.contentOffset = CGPointMake(0, 44)
3.) tableView(tableView: UITableView, numberOfRowsInSection section: Int))
let numOfYourRows = YOUR LOGIC
if numOfYourRows > minimumCellNum {
return numOfYourRows
} else {
return minimumCellNum!
}
4.) selection
속성이 인 빈 셀을 None
스토리 보드와tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)
if indexPath.row < numOfYourRows {
return YOUR CUSTOM CELL
} else {
let cell = tableView.dequeueReusableCellWithIdentifier("EmptyCell", forIndexPath: indexPath) as! UITableViewCell
return cell
}
5.) tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
if tableView == self.tableView {
if numOfYourRows < (indexPath.row + 1) {
return
}
YOUR LOGIC OF SELECTING A CELL
}
이것은 완벽한 솔루션은 아니지만 iOS 8에서 실제로 작동하는 유일한 해결 방법입니다. 깔끔한 솔루션이 있는지 알고 싶습니다.
콘텐츠 오프셋은가는 길이지만 100 % 작동하지 않습니다.
estimatedRowHeight
고정 된 숫자 로 설정하면 작동하지 않습니다 . 아직 해결 방법을 모르겠습니다. 내가 만든 프로젝트 문제 (들)을 보여주는를하고 내가 만든 레이더 애플을.
모든 것을 설정하는 방법에 대한 신속한 예제를 원한다면 프로젝트를 확인하십시오.
tableview에 데이터가 없으면 수락 된 답변이 중단됩니다. 그리고 viewDidLoad에 추가하면 특정 상황에서 작동하지 않을 수 있습니다.
[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; // crashes if no rows/data
따라서 대신 다음 코드 줄을 추가하십시오.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[yourTableView setContentOffset:CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height)];
}
솔직히, 어떤 답변도 실제로 문제를 해결하지 못했습니다. 테이블보기에 행이 없거나 행 높이가 다른 경우이 답변으로는 충분하지 않습니다.
작동하는 유일한 것 :
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.tableView.contentOffset = (CGPoint){.y = self.tableView.contentOffset.y + self.searchController.searchBar.frame.size.height};
}
tableView가 비어있을 때 "Notes"앱이 항목을 검색 할 수 없음을 발견했습니다. 그래서 -(void)addSubview:(UIView *)view
처음에는 빈 테이블을 추가하는 데 사용 하는 것 같습니다. 데이터 소스 배열에 항목을 추가하면 다른 코드를 실행하여 tableView를로드합니다.
그래서 내 해결책은 다음과 같습니다.
if([self.arrayList count] > 0)
{
[self.tableView reloadData]; //use jdandrea's code to scroll view when cell==nil in cellForRowAtIndexPath
self.tableView.scrollEnabled = YES;
}
else
{
tableBlank = [[UITableView alloc]initWithFrame:CGRectMake(0,0,320,416) style:UITableViewStylePlain] autorelease];
tableBlank.delegate = self;
tableBlank.dataSource = self;
[self.view addSubview:tableBlank];
}
도움이 되었기를 바랍니다 :-)
tableView의 경계를 변경하면 내부에서 수행 할 수 있으며 viewDidLoad
테이블이 비어 있는지 여부에 대해 걱정할 필요가 없습니다 (예외를 피하기 위해).
CGRect newBounds = self.tableView.bounds;
newBounds.origin.y = newBounds.origin.y + self.searchBar.bounds.size.height;
self.tableView.bounds = newBounds;
사용자가 테이블을 아래로 스크롤하면 검색 창이 나타나고 정상적으로 작동합니다.
이 질문에 대한 다른 답변은 전혀 작동하지 않았거나 tableView에 행이 0 개일 때 이상한 동작이 있거나 상위 항목과 중첩 된 항목 사이를 앞뒤로 이동할 때 스크롤 위치를 엉망으로 만들었습니다. 이것은 나를 위해 일했습니다 (목표는로드시 UISearchBar를 숨기는 것입니다).
public override func viewWillAppear(animated: Bool) {
if self.tableView.contentOffset.y == 0 {
self.tableView.contentOffset = CGPoint(x: 0.0, y: self.searchBar.frame.size.height)
}
}
설명
언제 tableView
UISearchBar가 표시되면 나타난다이 코드 검사 (의미 볼 y
의 위치 contentOffset
이며, 일명 스크롤 위치 0
). 그렇다면 단순히 searchBar의 높이를 아래로 스크롤합니다. searchBar가 표시되지 않는 경우 (의 더 큰 항목 목록을 생각해 tableView
보십시오) tableView
중첩 된 광고 항목에서 돌아올 때 위치가 엉망이되므로을 시도하고 스크롤하지 않습니다 .
참고
사항 단일 책임을 보장하고 코드에서 언제든지 호출 할 수있는 재사용 성을 제공하기 위해이 코드를 별도의 메서드에 넣는 것이 좋습니다.
테이블에 항상 하나 이상의 행이있는 경우 테이블의 첫 번째 행으로 스크롤하면 검색 창이 자동으로 숨겨집니다.
let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.selectRowAtIndexPath (firstIndexPath, animated : false, scrollPosition : .Top)
viewDidLoad에 위의 코드를 넣으면 tableView가 아직로드되지 않았기 때문에 오류가 발생하므로 tableView가 이미로드 되었기 때문에 viewDidAppear 에 넣어야합니다 .
viewDidAppear 에 넣으면 tableView를 열 때마다 맨 위로 스크롤됩니다.
UITabBar View Controller이거나 segue를 수행 한 다음 돌아올 때와 같이 tableView가 열려있는 경우이 동작을 원하지 않을 수 있습니다. 초기로드시 맨 위로 스크롤하도록하려면 변수를 만들어 초기로드인지 확인하여 한 번만 맨 위로 스크롤되도록 할 수 있습니다.
먼저 뷰 컨트롤러 클래스에서 isInitialLoad라는 변수를 정의하고 "true"로 설정합니다.
var isInitialLoad = true
그런 다음 viewDidAppear 에서 isInitialLoad가 true인지 확인 하고 true이면 맨 위로 스크롤하여 isInitialLoad 변수를 false로 설정합니다.
if isInitialLoad {
let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.selectRowAtIndexPath(firstIndexPath, animated: false, scrollPosition: .Top)
isInitialLoad = false
}
아래 코드는 나를 위해 일하고 있습니다.
self.tableView.contentOffset = CGPointMake(0.0, 44.0);
콘텐츠 오프셋 및 scrollToIndexpath 설정을 시도했지만 만족스럽게 작동하지 않았습니다. viewDidLoad에서 searchBar로 tableHeaderView의 설정을 제거하고 아래와 같이 scrollview delegate에 설정했습니다.
override func scrollViewWillBeginDragging(scrollView: UIScrollView) {
if scrollView.contentOffset.y < 0 && tableView.tableHeaderView == nil {
tableView.tableHeaderView = searchController.searchBar
tableView.setContentOffset(CGPointMake(0, scrollView.contentOffset.y + searchController.searchBar.frame.size.height), animated: false)
}
}
이것은 마치 매력처럼 작동했습니다. 콘텐츠 오프셋 설정은 부드러운 스크롤을위한 것입니다.
이 scrollToRowAtIndexPath
메서드는 테이블에 행이없는 경우 충돌을 일으 킵니다.
UITableView는 스크롤보기 일 뿐이므로 콘텐츠 오프셋을 간단히 변경할 수 있습니다.
이것은 검색 바가 tableHeaderView로 있는지 확인하고 스크롤하여 숨긴다고 가정합니다.
if let searchHeight = tableView.tableHeaderView?.frame.height {
tableView.setContentOffset(CGPoint.init(x: 0, y:searchHeight ), animated: false)
}
상태 표시 줄 과 탐색 표시 줄 을 고려 하는 것을 잊지 마십시오 . 내 테이블 뷰 컨트롤러는 내비게이션 컨트롤러에 내장되어 있습니다 viewDidAppear
.
tableView.contentOffset = CGPointMake(0, -20) // -20 = 44 (search bar height) - 20 (status bar height) - 44 (navigation bar height)
나를 위해 일했습니다.
Swift의 경우 :
검색 창의 높이와 같아야하는 tableview 콘텐츠 y 오프셋을 만드세요.
self.tableView.contentOffset = CGPointMake(0, self.searchController.searchBar.frame.size.height)
스위프트 3
빈 테이블에서도 작동합니다!
내 환경에서는 xib 파일로 사용자 지정 셀을로드하고 rowHeight는 자동으로 설정됩니다.
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
self.tableView.contentOffset = CGPoint(x: 0, y: self.tableView.contentOffset.y + self.searchController.searchBar.bounds.height)
}
비슷한 문제가있었습니다. 이 문제를 해결하기 위해 찾은 유일한 방법은 UITableView contentOffset 속성에서 키 값 관찰자를 사용하는 것입니다.
일부 디버깅 후 테이블보기 내용 크기가 tableview보다 작은 경우 문제가 발생한다는 것을 깨달았습니다. viewWillAppear에서 KVO를 시작합니다. 그리고보기가 나타난 후 0.3 초 후에 KVO를 중지합니다. contentOffset이 0.0이 될 때마다 KVO는 반응하고 검색 창 높이에 contentOffset을 설정합니다. 뷰 레이아웃이 뷰가 나타난 후에도 contentOffset을 재설정하기 때문에 0.3 초 후에 비동기식 KVO를 중지합니다.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
}
-(void)viewDidAppear:(BOOL)animated{
__weak typeof (self) weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf.tableView removeObserver:self forKeyPath:@"contentOffset"];});
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"contentOffset"] && self.tableView.contentOffset.y == 0.0) {
self.tableView.contentOffset = CGPointMake(0, CGRectGetHeight(self.tableView.tableHeaderView.frame));
}
}
-(void)dealloc {
[self.tableView removeObserver:self forKeyPath:@"contentOffset"];
}
참고 URL : https://stackoverflow.com/questions/1081381/iphone-hide-uitableview-search-bar-by-default
'IT' 카테고리의 다른 글
OS X Mavericks 용 Eclipse Kepler, Java SE 6 요청 (0) | 2020.09.15 |
---|---|
C ++에서 배열을 선언하는 방법은 무엇입니까? (0) | 2020.09.15 |
WPF : TextBox에서 프로그래밍 방식으로 포커스를 제거하는 방법 (0) | 2020.09.15 |
Java에서 null은 무엇입니까? (0) | 2020.09.15 |
배열에서 가장 높은 키 / 보안 검색 (0) | 2020.09.15 |