Facebook 숨기기 / 표시 확장 / 계약 탐색 모음 모방
새로운 iOS7 Facebook iPhone 앱에서 사용자가 위로 스크롤하면 navigationBar
점차 사라지는 지점 까지 점차적으로 숨겨집니다. 그런 다음 사용자가 아래로 스크롤하면 navigationBar
점차적으로 표시됩니다.
이 행동을 어떻게 직접 구현 하시겠습니까? 다음 해결책을 알고 있지만 즉시 사라지고 사용자의 스크롤 제스처 속도와 관련이 없습니다.
[navigationController setNavigationBarHidden: YES animated:YES];
"확장 / 축소"동작을 가장 잘 설명하는 방법을 잘 모르기 때문에 이것이 중복되지 않기를 바랍니다.
@peerless가 제공하는 솔루션은 훌륭한 시작이지만 스크롤 속도를 고려하지 않고 드래그가 시작될 때마다 애니메이션을 시작합니다. 이로 인해 Facebook 앱보다 더 쾌적하게 경험할 수 있습니다. Facebook의 행동과 일치하려면 다음을 수행해야합니다.
- 탐색 속도에 비례하는 속도로 탐색 표시 줄 숨기기 / 표시
- 막대가 부분적으로 숨겨져있을 때 스크롤이 중지되면 애니메이션을 시작하여 막대를 완전히 숨 깁니다
- 막대가 줄어들면 탐색 모음의 항목이 희미 해집니다.
먼저 다음 속성이 필요합니다.
@property (nonatomic) CGFloat previousScrollViewYOffset;
그리고 UIScrollViewDelegate
방법 은 다음과 같습니다 .
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect frame = self.navigationController.navigationBar.frame;
CGFloat size = frame.size.height - 21;
CGFloat framePercentageHidden = ((20 - frame.origin.y) / (frame.size.height - 1));
CGFloat scrollOffset = scrollView.contentOffset.y;
CGFloat scrollDiff = scrollOffset - self.previousScrollViewYOffset;
CGFloat scrollHeight = scrollView.frame.size.height;
CGFloat scrollContentSizeHeight = scrollView.contentSize.height + scrollView.contentInset.bottom;
if (scrollOffset <= -scrollView.contentInset.top) {
frame.origin.y = 20;
} else if ((scrollOffset + scrollHeight) >= scrollContentSizeHeight) {
frame.origin.y = -size;
} else {
frame.origin.y = MIN(20, MAX(-size, frame.origin.y - scrollDiff));
}
[self.navigationController.navigationBar setFrame:frame];
[self updateBarButtonItems:(1 - framePercentageHidden)];
self.previousScrollViewYOffset = scrollOffset;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self stoppedScrolling];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView
willDecelerate:(BOOL)decelerate
{
if (!decelerate) {
[self stoppedScrolling];
}
}
다음과 같은 도우미 메소드가 필요합니다.
- (void)stoppedScrolling
{
CGRect frame = self.navigationController.navigationBar.frame;
if (frame.origin.y < 20) {
[self animateNavBarTo:-(frame.size.height - 21)];
}
}
- (void)updateBarButtonItems:(CGFloat)alpha
{
[self.navigationItem.leftBarButtonItems enumerateObjectsUsingBlock:^(UIBarButtonItem* item, NSUInteger i, BOOL *stop) {
item.customView.alpha = alpha;
}];
[self.navigationItem.rightBarButtonItems enumerateObjectsUsingBlock:^(UIBarButtonItem* item, NSUInteger i, BOOL *stop) {
item.customView.alpha = alpha;
}];
self.navigationItem.titleView.alpha = alpha;
self.navigationController.navigationBar.tintColor = [self.navigationController.navigationBar.tintColor colorWithAlphaComponent:alpha];
}
- (void)animateNavBarTo:(CGFloat)y
{
[UIView animateWithDuration:0.2 animations:^{
CGRect frame = self.navigationController.navigationBar.frame;
CGFloat alpha = (frame.origin.y >= y ? 0 : 1);
frame.origin.y = y;
[self.navigationController.navigationBar setFrame:frame];
[self updateBarButtonItems:alpha];
}];
}
약간 다른 동작을하려면 스크롤 할 때 막대의 위치를 바꾸는 선 (의 else
블록 scrollViewDidScroll
)을 다음과 같이 바꾸십시오 .
frame.origin.y = MIN(20,
MAX(-size, frame.origin.y -
(frame.size.height * (scrollDiff / scrollHeight))));
막대가 절대 값 대신 마지막 스크롤 비율을 기준으로 배치되어 페이드 속도가 느려집니다. 원래 동작은 Facebook과 비슷하지만이 기능도 마음에 듭니다.
참고 :이 솔루션은 iOS 7 이상입니다. 이전 버전의 iOS를 지원하는 경우 필요한 검사를 추가하십시오.
편집 : iOS 8 이상에서만 가능합니다.
당신은 사용을 시도 할 수 있습니다
self.navigationController.hidesBarsOnSwipe = YES;
나를 위해 작동합니다.
신속하게 코딩하는 경우이 방법을 사용해야합니다 ( https://stackoverflow.com/a/27662702/2283308 )
navigationController?.hidesBarsOnSwipe = true
여기에 또 하나의 구현은 다음과 같습니다 TLYShyNavBar의 v1.0.0 개발자가 출시!
나는 제공된 솔루션을 시도한 후에 나 자신을 만들기로 결정했고, 나에게는 성능이 좋지 않았거나 진입 및 보일러 판 코드의 장벽이 높았거나 탐색 표시 줄 아래의 확장보기가 없었습니다. 이 구성 요소를 사용하려면 다음을 수행하십시오.
self.shyNavBarManager.scrollView = self.scrollView;
아, 그것은 우리 자신의 응용 프로그램에서 전투 테스트되었습니다.
내 GTScrollNavigationBar를 볼 수 있습니다 . UIScrollView의 스크롤을 기반으로 스크롤하도록 UINavigationBar를 서브 클래스 화했습니다.
참고 : OPAQUE 탐색 막대가있는 경우 탐색 막대가 숨겨 질 때 스크롤보기가 확장되어야합니다. 이것이 바로 GTScrollNavigationBar의 기능입니다. (예를 들어 iOS의 Safari와 같습니다.)
iOS8에는 탐색 모음을 무료로 숨기는 속성이 포함되어 있습니다. 이를 보여주는 WWDC 비디오가 있습니다. "iOS 8의 View Controller Advancements"를 검색하십시오.
예 :
class QuotesTableViewController: UITableViewController {
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
navigationController?.hidesBarsOnSwipe = true
}
}
다른 속성들 :
class UINavigationController : UIViewController {
//... truncated
/// When the keyboard appears, the navigation controller's navigationBar toolbar will be hidden. The bars will remain hidden when the keyboard dismisses, but a tap in the content area will show them.
@availability(iOS, introduced=8.0)
var hidesBarsWhenKeyboardAppears: Bool
/// When the user swipes, the navigation controller's navigationBar & toolbar will be hidden (on a swipe up) or shown (on a swipe down). The toolbar only participates if it has items.
@availability(iOS, introduced=8.0)
var hidesBarsOnSwipe: Bool
/// The gesture recognizer that triggers if the bars will hide or show due to a swipe. Do not change the delegate or attempt to replace this gesture by overriding this method.
@availability(iOS, introduced=8.0)
var barHideOnSwipeGestureRecognizer: UIPanGestureRecognizer { get }
/// When the UINavigationController's vertical size class is compact, hide the UINavigationBar and UIToolbar. Unhandled taps in the regions that would normally be occupied by these bars will reveal the bars.
@availability(iOS, introduced=8.0)
var hidesBarsWhenVerticallyCompact: Bool
/// When the user taps, the navigation controller's navigationBar & toolbar will be hidden or shown, depending on the hidden state of the navigationBar. The toolbar will only be shown if it has items to display.
@availability(iOS, introduced=8.0)
var hidesBarsOnTap: Bool
/// The gesture recognizer used to recognize if the bars will hide or show due to a tap in content. Do not change the delegate or attempt to replace this gesture by overriding this method.
@availability(iOS, introduced=8.0)
unowned(unsafe) var barHideOnTapGestureRecognizer: UITapGestureRecognizer { get }
}
http://natashatherobot.com/navigation-bar-interactions-ios8/을 통해 발견
나는 그것에 대한 빠르고 더러운 해결책이 있습니다. 심층 테스트를하지 않았지만 여기 아이디어가 있습니다.
이 속성은 내 UITableViewController 클래스의 탐색 모음에 모든 항목을 유지합니다.
@property (strong, nonatomic) NSArray *navBarItems;
동일한 UITableViewController 클래스에 다음이 있습니다.
-(void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
{
if([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0f){
return;
}
CGRect frame = self.navigationController.navigationBar.frame;
frame.origin.y = 20;
if(self.navBarItems.count > 0){
[self.navigationController.navigationBar setItems:self.navBarItems];
}
[self.navigationController.navigationBar setFrame:frame];
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0f){
return;
}
CGRect frame = self.navigationController.navigationBar.frame;
CGFloat size = frame.size.height - 21;
if([scrollView.panGestureRecognizer translationInView:self.view].y < 0)
{
frame.origin.y = -size;
if(self.navigationController.navigationBar.items.count > 0){
self.navBarItems = [self.navigationController.navigationBar.items copy];
[self.navigationController.navigationBar setItems:nil];
}
}
else if([scrollView.panGestureRecognizer translationInView:self.view].y > 0)
{
frame.origin.y = 20;
if(self.navBarItems.count > 0){
[self.navigationController.navigationBar setItems:self.navBarItems];
}
}
[UIView beginAnimations:@"toggleNavBar" context:nil];
[UIView setAnimationDuration:0.2];
[self.navigationController.navigationBar setFrame:frame];
[UIView commitAnimations];
}
그것은 ios> = 7에만 해당됩니다. 추악한 것으로 알고 있지만 이것을 달성하는 빠른 방법입니다. 모든 의견 / 제안을 환영합니다 :)
이것은 iOS 8 이상에서 작동하며 상태 표시 줄이 여전히 배경을 유지하도록합니다.
self.navigationController.hidesBarsOnSwipe = YES;
CGRect statuBarFrame = [UIApplication sharedApplication].statusBarFrame;
UIView *statusbarBg = [[UIView alloc] initWithFrame:statuBarFrame];
statusbarBg.backgroundColor = [UIColor blackColor];
[self.navigationController.view addSubview:statusbarBg];
상태 표시 줄을 누를 때 탐색 표시 줄을 표시하려면 다음을 수행하십시오.
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView {
self.navigationController.navigationBarHidden = NO;
}
여기 내 구현이 있습니다 : SherginScrollableNavigationBar .
내 접근 방식에서는 의 상태 KVO
를 관찰 UIScrollView
하는 데 사용하므로 대리자를 사용할 필요가 없습니다 (필요한 다른 용도 로이 대리자를 사용할 수 있습니다).
이 솔루션을 사용 해보고 왜 이것이 이전 답변만큼 좋지 않은지 알려주세요.
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
if (fabs(velocity.y) > 1)
[self hideTopBar:(velocity.y > 0)];
}
- (void)hideTopBar:(BOOL)hide
{
[self.navigationController setNavigationBarHidden:hide animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:hide withAnimation:UIStatusBarAnimationSlide];
}
내가 이것을 달성 한 방법은 다음과 같습니다.
로보기 컨트롤러를 등록 UIScrollViewDelegate
하여의를 UITableView
예를 들면.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
UIScrollViewDelegate
메소드 내 에서 새 contentOffset을 가져 UINavigationBar
와서 위 또는 아래로 적절하게 변환 할 수 있습니다 .
일부 임계 값과 설정 및 계산할 수있는 요소를 기반으로 하위보기의 알파를 설정할 수도 있습니다.
그것이 도움이되기를 바랍니다!
Iwburk의 답변 외에도 비 사용자 정의 탐색 모음의 알파 문제를 해결하고 viewWillDisappear 메소드에서 탐색 모음을 재설정하기 위해 다음을 추가했습니다.
- (void)updateBarButtonItems:(CGFloat)alpha
{
for (UIView *view in self.navigationController.navigationBar.subviews) {
NSString *className = NSStringFromClass([view class]);
if ( ![className isEqualToString:@"_UINavigationBarBackground"] ) {
view.alpha = alpha;
}
}
}
- (void)resetNavigationBar {
CGRect frame = self.navigationController.navigationBar.frame;
frame.origin.y = 20;
[self.navigationController.navigationBar setFrame:frame];
[self updateBarButtonItems:1.0f];
}
나는 어떤 스타일과 행동을 허용하는 솔루션을 찾고있었습니다. 많은 응용 프로그램에서 막대 응축 동작이 다르다는 것을 알 수 있습니다. 물론 막대 모양은 앱마다 완전히 다릅니다.
https://github.com/bryankeller/BLKFlexibleHeightBar/ 를 사용 하여이 문제에 대한 솔루션을 만들었습니다.
막대가 줄어들고 커지는 방법과시기를 제어하기 위해 고유 한 동작 규칙을 정의 할 수 있으며 막대의 하위 뷰가 막대에 응결되거나 성장하는 방식을 정확하게 정의 할 수 있습니다.
생각할 수있는 모든 종류의 헤더 막대를 만들 수있는 많은 유연성을 원한다면 내 프로젝트를 살펴보십시오.
UITableView에 관한 사용자 정의 헤더가 필요한 상황 에서이 동작을 에뮬레이션하려고했습니다. 페이지의 다른 여러 항목 아래에 있고 내 머리글이 기본 "도킹"동작을 따르기를 원했기 때문에 내 "탐색"막대를 굴 렸습니다. UITableView / UIScrollView를 Facebook / Instagram / Chrome / etc와 비슷한 스타일로 다른 객체와 함께 UITableView / UIScrollView를 조정하는 매우 영리하고 간결한 방법을 찾았습니다. 앱.
내 .xib 파일에서 자유 구성 요소 뷰에 내 구성 요소를로드했습니다. http://imgur.com/0z9yebJ (죄송합니다.
왼쪽 사이드 바에서 테이블은 기본 헤더보기 뒤에 정렬됩니다. 스크린 샷에서 알 수는 없지만 기본 헤더보기와 동일한 y 위치도 있습니다. UITableView의 contentInset 속성은 보이지 않게 확장되므로 76 (메인 헤더 뷰의 높이)으로 설정됩니다.
UIScrollView와 함께 메인 헤더 뷰를 슬라이드 업하기 위해 UIScrollViewDelegate의 scrollViewDidScroll 메소드를 사용하여 계산을 수행하고 UIScrollView의 contentInset과 메인 헤더 뷰의 프레임을 변경합니다.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
UIEdgeInsets insets = scrollView.contentInset;
//tableViewInsetDelta and tableViewOriginalInsetValue are NSInteger variables that I set to 0 and 76, respectively, in viewDidLoad
tableViewInsetDelta = tableViewOriginalInsetValue + scrollView.contentOffset.y;
insets.top = tableViewOriginalInsetValue - tableViewInsetDelta;
if (scrollView.contentOffset.y > -76 && scrollView.contentOffset.y < 0) {
[scrollView setContentInset:insets];
self.pathTitleContainer.frame = CGRectMake(self.pathTitleContainer.frame.origin.x, 44 - tableViewInsetDelta, self.pathTitleContainer.frame.size.width, self.pathTitleContainer.frame.size.height);
} else if (scrollView.contentOffset.y > 0) {
insets.top = 0;
[scrollView setContentInset:insets];
self.pathTitleContainer.frame = CGRectMake(self.pathTitleContainer.frame.origin.x, -32, self.pathTitleContainer.frame.size.width, self.pathTitleContainer.frame.size.height);
} else if (scrollView.contentOffset.y < -76) {
insets.top = 76;
[scrollView setContentInset:insets];
self.pathTitleContainer.frame = CGRectMake(self.pathTitleContainer.frame.origin.x, 44, self.pathTitleContainer.frame.size.width, self.pathTitleContainer.frame.size.height);
}
}
첫 번째 if 문은 대부분의 무거운 작업을 수행하지만 사용자가 강제로 끌고 scrollViewDidScroll에 전송 된 초기 contentOffset 값이 첫 번째 if 문 범위를 벗어난 상황을 처리하기 위해 다른 두 개를 포함해야했습니다 .
궁극적으로 이것은 나를 위해 정말 잘 작동합니다. 부풀어 오른 하위 클래스로 프로젝트를로드하는 것을 싫어합니다. 이것이 성능면에서 최상의 솔루션인지 여부를 말할 수는 없습니다 (항상 호출되기 때문에 scrollViewDidScroll에 코드를 넣는 것을 주저했습니다).하지만 코드 발자국은 내가 본 것 중 가장 작습니다. 이 문제에 대한 해결책이며 UIScrollView에 UITableView를 중첩시키지 않아도됩니다 (Apple은 문서 및 터치 이벤트에서 UITableView에서 약간 펑키하게 만듭니다). 이것이 누군가를 돕기를 바랍니다!
HidingNavigationBar 원하는 경우탐색 막대 와 탭 막대를 숨기는 훌륭한 프로젝트입니다.
HidingNavigationBar는 다음 뷰 요소 숨기기 / 표시를 지원합니다.
UINavigationBar
UINavigationBar 및 확장 UIView
UINavigationBar 및 UIToolbar
UINavigationBar 및 UITabBar
https://github.com/tristanhimmelman/HidingNavigationBar
GTScrollNavigationBar를 구현하려고 시도했지만 앱에서 자동 레이아웃 제약 조건을 수정해야했습니다. 다른 사람이 자동 레이아웃 으로이 작업을 수행 해야하는 경우를 대비하여 GitHub에 구현 예제를 작성하기로 결정했습니다. 내가 대부분의 다른 구현에서 가지고있는 다른 문제는 사람들이 스크롤보기의 크기를 동시에 스크롤하고 조정하는 동안 생성하는 시차 스크롤 효과를 피하기 위해 스크롤보기의 경계를 설정하지 않는다는 것입니다.
자동 레이아웃 으로이 작업을 수행 해야하는 경우 JSCollapsingNavBarViewController를 확인하십시오 . 하나는 탐색 모음 만 있고 다른 하나는 탐색 모음을 축소하기 전에 축소되는 탐색 모음 아래에 하위 막대가있는 두 가지 버전을 포함했습니다.
나는이 방법으로 그것을 시도했지만 도움이되기를 바랍니다. 대리자 메서드에서 코드를 구현하고 원하는보기 / 하위보기로 설정하십시오.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGRect frame=self.view.frame;
CGRect resultFrame=CGRectZero;
if(scrollView.contentOffset.y==0 || scrollView.contentOffset.y<0){
self.lastContentOffset=0;
self.offset=0;
resultFrame=CGRectMake(0, frame.size.height-(40-self.offset.intValue), frame.size.width, 40-self.offset.intValue);
// Pass the resultFrame
[self showHide:YES withFrame:resultFrame];
}else if (self.lastContentOffset > scrollView.contentOffset.y){
NSNumber *temp=[NSNumber numberWithDouble:self.lastContentOffset-scrollView.contentOffset.y];
if(temp.intValue>40 || self.offset.intValue<temp.intValue){
self.offset=[NSNumber numberWithInt:0];
resultFrame=CGRectMake(0, frame.size.height-(40-self.offset.intValue), frame.size.width, 40-self.offset.intValue);
// Pass the resultFrame
[self showHide:YES withFrame:resultFrame];
}else{
if(temp.intValue>0){
self.offset=[NSNumber numberWithInt:self.offset.intValue-temp.intValue];
resultFrame=CGRectMake(0, frame.size.height-(40-self.offset.intValue), frame.size.width, 40-self.offset.intValue);
// Pass the resultFrame
[self showHide:YES withFrame:resultFrame];
}
}
}else if (self.lastContentOffset < scrollView.contentOffset.y){
NSNumber *temp=[NSNumber numberWithDouble:scrollView.contentOffset.y-self.lastContentOffset];
if(self.offset.intValue>40 || (self.offset.intValue+temp.intValue)>40){
self.offset=[NSNumber numberWithInt:40];
// Pass the resultFrame
[self showHide:NO withFrame:resultFrame];
}else{
self.offset=[NSNumber numberWithInt:self.offset.intValue+temp.intValue];
resultFrame=CGRectMake(0, frame.size.height-(40-self.offset.intValue), frame.size.width, 40-self.offset.intValue);
// Pass the resultFrame
[self showHide:YES withFrame:resultFrame];
}
}
self.lastContentOffset = scrollView.contentOffset.y;
}
-(void)showHide:(Boolean)boolView withFrame:(CGRect)frame{
if(showSRPFilter){
//Assign value of "frame"to any view on which you wan to to perform animation
}else{
//Assign value of "frame"to any view on which you wan to to perform animation
}
}
@Iwburk의 대답의 확장 ... 탐색 모음의 원점을 변경하는 대신 탐색 모음의 크기를 확장 / 축소해야했습니다.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGRect frame = self.previousRect; // a property set in the init method to hold the initial size of the uinavigationbar
CGFloat size = frame.size.height;
CGFloat framePercentageHidden = ((MINIMUMNAVBARHEIGHT - frame.origin.y) / (frame.size.height - 1));
CGFloat scrollOffset = scrollView.contentOffset.y;
CGFloat scrollDiff = scrollOffset - self.previousScrollViewYOffset;
CGFloat scrollHeight = scrollView.frame.size.height;
CGFloat scrollContentSizeHeight = scrollView.contentSize.height + scrollView.contentInset.bottom;
if (scrollOffset <= -scrollView.contentInset.top) {
frame.origin.y = -MINIMUMNAVBARHEIGHT;
} else if ((scrollOffset + scrollHeight) >= scrollContentSizeHeight) {
frame.origin.y = -size;
} else {
frame.origin.y = MIN(-MINIMUMNAVBARHEIGHT, MAX(-size, frame.origin.y - scrollDiff));
}
self.previousRect = CGRectMake(0, frame.origin.y, self.jsExtendedBarView.frame.size.width, 155);
self.layoutConstraintExtendedViewHeight.constant = MAXIMUMNAVBARHEIGHT + frame.origin.y + MINIMUMNAVBARHEIGHT;
[self updateBarButtonItems:(1 - framePercentageHidden)];
self.previousScrollViewYOffset = scrollOffset;
}
stoppedScrolling
아직 방법으로 작동하지 않습니다.
이 모든 접근 방식은 지나치게 복잡해 보입니다.
class ViewController: UIViewController, UIScrollViewDelegate {
var originalNavbarHeight:CGFloat = 0.0
var minimumNavbarHeight:CGFloat = 0
weak var scrollView:UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// setup delegates
scrollView.delegate = self
// save the original nav bar height
originalNavbarHeight = navigationController!.navigationBar.height
}
func scrollViewDidScroll(scrollView: UIScrollView) {
// will relayout subviews
view.setNeedsLayout() // calls viewDidLayoutSubviews
}
override func viewDidLayoutSubviews() {
var percentageScrolled = min(scrollView.contentOffset.y / originalNavbarHeight, 1)
navigationController?.navigationBar.height = min(max((1 - percentageScrolled) * originalNavbarHeight, minimumNavbarHeight), originalNavbarHeight)
// re-position and scale scrollview
scrollView.y = navigationController!.navigationBar.height + UIApplication.sharedApplication().statusBarFrame.height
scrollView.height = view.height - scrollView.y
}
override func viewWillDisappear(animated: Bool) {
navigationController?.navigationBar.height = originalNavbarHeight
}
}
Objective-C에 주어진 모든 답을 찾았습니다. 이것은 Swift 3의 답변입니다. 이것은 매우 일반적인 코드이며 직접 사용할 수 있습니다. UIScrollView 및 UITableView와 함께 작동합니다.
var lastContentOffset: CGPoint? = nil
var maxMinus: CGFloat = -24.0
var maxPlus: CGFloat = 20.0
var initial: CGFloat = 0.0
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Alarm Details"
self.lastContentOffset = self.alarmDetailsTableView.contentOffset
initial = maxPlus
}
func scrollViewDidScroll(_ scrollView: UIScrollView)
{
var navigationBarFrame: CGRect = self.navigationController!.navigationBar.frame
let currentOffset = scrollView.contentOffset
if (currentOffset.y > (self.lastContentOffset?.y)!) {
if currentOffset.y > 0 {
initial = initial - fabs(CGFloat(currentOffset.y - self.lastContentOffset!.y))
}
else if scrollView.contentSize.height < scrollView.frame.size.height {
initial = initial + fabs(CGFloat(currentOffset.y - self.lastContentOffset!.y))
}
}
else {
if currentOffset.y < scrollView.contentSize.height - scrollView.frame.size.height {
initial = initial + fabs(CGFloat(currentOffset.y - self.lastContentOffset!.y))
}
else if scrollView.contentSize.height < scrollView.frame.size.height && initial < maxPlus {
initial = initial - fabs(CGFloat(currentOffset.y - self.lastContentOffset!.y))
}
}
initial = (initial <= maxMinus) ? maxMinus : initial
initial = (initial >= maxPlus) ? maxPlus : initial
navigationBarFrame.origin.y = initial
self.navigationController!.navigationBar.frame = navigationBarFrame
scrollView.frame = CGRect(x: 0.0, y: initial + navigationBarFrame.size.height , width: navigationBarFrame.size.width, height: self.view.frame.size.height - (initial + navigationBarFrame.size.height))
let framePercentageHidden: CGFloat = ((20 - navigationBarFrame.origin.y) / (navigationBarFrame.size.height));
self.lastContentOffset = currentOffset;
self.updateBarButtonItems(alpha: 1 - framePercentageHidden)
}
func updateBarButtonItems(alpha: CGFloat)
{
self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.darkGray.withAlphaComponent(alpha)]
self.navigationController?.navigationBar.isUserInteractionEnabled = (alpha < 1) ? false: true
guard (self.navigationItem.leftBarButtonItems?.count) != nil else { return }
for (_, value) in self.navigationItem.leftBarButtonItems!.enumerated() {
value.customView?.alpha = alpha
}
guard (self.navigationItem.rightBarButtonItems?.count) != nil else { return }
for (_, value) in (self.navigationItem.rightBarButtonItems?.enumerated())! {
value.customView?.alpha = alpha
}
}
탐색 항목으로 알파를 설정하는 논리는 @ WayneBurkett 답변 에서 복사 되어 Swift 3에서 다시 작성되었습니다.
'IT story' 카테고리의 다른 글
iPhone App에서 기기의 화면 해상도를 감지하는 방법 (0) | 2020.07.03 |
---|---|
X-Powered-By 제거 (0) | 2020.07.03 |
HTTP를 통해 바이너리 파일을 다운로드하려면 어떻게합니까? (0) | 2020.07.03 |
GDB로 단일 중단 점을 어떻게 제거합니까? (0) | 2020.07.03 |
ggplot2에서 한계 히스토그램이있는 산점도 (0) | 2020.07.03 |