नेविगेशन बार को Facebook छिपाने / दिखाने का विस्तार / अनुबंध करें


128

नए iOS7 फेसबुक iPhone ऐप में, जब उपयोगकर्ता स्क्रॉल करता है तो navigationBarधीरे-धीरे खुद को एक ऐसे बिंदु पर छिपाता है जहां यह पूरी तरह से गायब हो जाता है। फिर जब उपयोगकर्ता स्क्रॉल करता है तो navigationBarधीरे-धीरे खुद को दिखाता है।

आप स्वयं इस व्यवहार को कैसे लागू करेंगे? मैं निम्नलिखित समाधान से अवगत हूं, लेकिन यह तुरंत गायब हो जाता है और यह उपयोगकर्ता के स्क्रॉल इशारे की गति से बिल्कुल भी जुड़ा नहीं है।

[navigationController setNavigationBarHidden: YES animated:YES];

मुझे आशा है कि यह कोई डुप्लिकेट नहीं है क्योंकि मुझे यकीन नहीं है कि "विस्तार / अनुबंध" व्यवहार का वर्णन करने के लिए कितना अच्छा है।


2
समान मुद्दे: stackoverflow.com/questions/21929220/… ध्यान दें कि सफारी व्यवहार से पूरी तरह मेल खाना अविश्वसनीय रूप से मुश्किल है । वहाँ कुछ बहुत, बहुत जटिल नियम हैं!
फेटी

1
अपनी परियोजना में मैंने इस परियोजना का उपयोग किया और यह ठीक काम किया। इसके प्रलेखन पर एक नज़र डालें।
विनीसियस

github.com/bryankeller/BLKFlexibleHeightBar आपको वह करने देगा जो आप चाहते हैं और अधिक। यह आपको यह निर्दिष्ट करने की अनुमति देता है कि बार अपने संक्रमण के प्रत्येक चरण को अधिकतम से न्यूनतम तक कैसे देखता है। यहां तक ​​कि यह आपको अपने स्वयं के व्यवहार को निर्दिष्ट करने देता है, इसलिए यह सफारी, फेसबुक या किसी अन्य ऐप की तरह कार्य कर सकता है।
blkhp19

मैंने एक uinavigationbar का उपयोग नहीं किया, लेकिन इसके बजाय एक uiview जोड़ा। नेविगेशन बार की नकल करने वाला दृश्य स्क्रॉल के आधार पर विस्तार और अनुबंध करेगा। मैंने कार्य को प्राप्त करने के लिए scrollViewDidScroll प्रतिनिधि विधि का उपयोग किया। आप नीचे दिए गए स्रोत कोड को जांचना और निष्पादित करना चाह सकते हैं .. dropbox.com/s/b2c0zw6yvchaia5/FailedBanks.zip?dl=0
दीपक ठाकुर

जवाबों:


162

@ लेयरलेस द्वारा दिया गया समाधान एक शानदार शुरुआत है, लेकिन यह केवल एक एनीमेशन को किक करता है जब भी ड्रैगिंग शुरू होती है, बिना स्क्रॉल की गति पर विचार किए। यह फेसबुक ऐप में आपको मिलने वाले अनुभव की तुलना में अधिक है। फेसबुक के व्यवहार से मेल खाने के लिए, हमें निम्न करने की आवश्यकता है:

  • नावबार को उस दर पर छुपाना / दिखाना जो ड्रैग की दर के आनुपातिक है
  • अगर बार आंशिक रूप से छिपा हुआ है तो स्क्रॉल बंद हो जाता है तो बार को छुपाने के लिए एक एनीमेशन को बंद करें
  • बार सिकुड़ते ही नबार की वस्तुओं को फीका कर देते हैं।

सबसे पहले, आपको निम्नलिखित संपत्ति की आवश्यकता होगी:

@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))));

यह एक पूर्ण राशि के बजाय अंतिम स्क्रॉल प्रतिशत के आधार पर बार को स्थिति देता है, जिसके परिणामस्वरूप धीमी गति से फीका पड़ता है। मूल व्यवहार फेसबुक की तरह अधिक है, लेकिन मुझे यह पसंद है।

नोट: यह समाधान केवल iOS 7+ है। यदि आप iOS के पुराने संस्करणों का समर्थन कर रहे हैं, तो आवश्यक जांच जोड़ना सुनिश्चित करें।


यह काम। सिवाय इसके कि आप मान रहे हैं कि बार के बटन आइटम में कस्टम दृश्य हैं। मेरे मामले में मेरे पास कोई कस्टम दृश्य नहीं है। इसलिए उपरोक्त बार बटन को छिपाता नहीं है। मुझे लगता है कि नेवर आइटमों को छिपाने और दिखाने के लिए @ बेपरवाह समाधान बेहतर है
धनुष

1
तुम सही हो। मैं इस सप्ताह के अंत में एक अधिक सामान्य समाधान पर ध्यान दे सकता हूं। के बजाय डिफ़ॉल्ट आइटम को लक्षित करने के लिए बहुत मुश्किल नहीं होना चाहिए customView
वेन

मैंने @ धनुष के मुद्दे को संबोधित नहीं किया है लेकिन मेरे पास एक अद्यतन है।
वेन

1
मैंने स्टॉक बार बटन के साथ समस्या को ठीक किया, लेकिन इस कोड में एक और मुद्दा है। तो ScrollViewके contentSizeफ्रेम से छोटी है, रपट की एनीमेशन काम नहीं करता है। यह भी सुनिश्चित करें कि आप सभी नेविगेशन आइटम के अल्फा को 1.0 में वापस सेट कर सकते हैं viewDidDisappear
लेगलेस २०'१४

1
क्या आपने नियंत्रकों पर इस समाधान की जाँच की है जो AutoLayout उपयोग किए जाते हैं? मेरे मामले में सब कुछ AutoLayout के बिना ठीक काम कर रहा है, लेकिन जब यह चालू होता है, तो यह अभी भी इसके नीचे कुछ अजीब सफेद पट्टी दिखाई देता है
एलाक्षैंडर बी

52

EDIT: केवल iOS 8 और इसके बाद के संस्करण के लिए।

आप उपयोग करने की कोशिश कर सकते हैं

self.navigationController.hidesBarsOnSwipe = YES;

मेरे लिये कार्य करता है।

यदि आपकी कोडिंग तेज़ी से हो तो आपको इस तरह से ( https://stackoverflow.com/a/27662702/22303030 से ) उपयोग करना होगा

navigationController?.hidesBarsOnSwipe = true

यह आईओएस <8.0 में उपलब्ध नहीं है
पेटार

1
जैसा कि pet60t0 ने कहा, और मैं माफी चाहता हूं, केवल iOS 8 और इसके बाद के संस्करण के लिए काम करता है।
पेड्रो रोमियो

4
उसके बाद आप इसे कैसे वापस लाएंगे?
C0D3

व्यवहार यह थोड़ा अजीब है। मैंने बहुत खोज नहीं की, लेकिन यदि आप इसे फिर से दिखाते हैं तो यह तेजी से स्क्रॉल करता है।
पेड्रो रोमियो

@ PedroRomão शानदार जवाब।
गगन_आईओएस

43

यहाँ एक और कार्यान्वयन है: TLYShyNavBar v1.0.0 जारी किया गया!

मैंने प्रदान किए गए समाधानों की कोशिश करने के बाद अपना खुद का बनाने का फैसला किया, और मेरे लिए, वे या तो खराब प्रदर्शन कर रहे थे, प्रवेश और बॉयलर प्लेट कोड की एक उच्च बाधा थी, या नावबार के नीचे विस्तार दृश्य का अभाव था। इस घटक का उपयोग करने के लिए, आपको बस इतना करना है:

self.shyNavBarManager.scrollView = self.scrollView;

ओह, और यह हमारे अपने ऐप में परीक्षण की गई लड़ाई है।


@TimArnold आपकी प्रतिक्रिया के लिए धन्यवाद! मैंने उस मुद्दे को ठीक कर लिया है, बस अभी तक फली को अद्यतन नहीं किया है> _ <अभी वह कर देगा! .. पॉड अपडेट!
माजिद

मैं इसे एक और शॉट दूँगा! धन्यवाद!
टिम कैमर

तुम्हारी सहायता सराहनीय है। लगता है कि आपकी प्रतिबद्ध मदद की। मुझे अभी भी एक अजीब मुद्दा मिल रहा है जहां मेरे UICollectionView को नौसेना पट्टी के रूप में ठीक से आकार नहीं दिया गया है, और इसलिए सेल जहां ऊपर जा रहे हैं, वहां उपयोग किए जाने वाले नेव बार को क्लिप किया जाता है, क्योंकि वे संग्रह दृश्य सीमा के बाहर हैं। क्या आप जानते हैं कि ऐसा क्यों हो सकता है?
टिम कैमर

4
आंकड़े: इस टिप्पणी को लिखने के बाद मेरे समाधान सेकंड मिले। मुझे यह सुनिश्चित करना extendedLayoutIncludesOpaqueBarsथा कि YESमेरेUICollectionViewController
टिम कैमर जूल

@TimArnold यह कमाल है! एक और लड़का था , जिसकी समस्या वही थी , और उम्मीद है कि आपका समाधान उसकी मदद करेगा।
माजिद

33

आप मेरे GTScrollNavigationBar पर एक नज़र डाल सकते हैं । मैंने UIScrollView की स्क्रॉलिंग के आधार पर इसे स्क्रॉल करने के लिए UINavigationBar को उप-वर्गित किया है।

नोट: यदि आपके पास एक OPAQUE नेविगेशन बार है, तो स्क्रॉलव्यू का विस्तार होना चाहिए क्योंकि नेविगेशन बार HIDDEN हो जाता है। यह वही है जो GTScrollNavigationBar करता है। (उदाहरण के लिए आईओएस पर सफारी।)


किसी को भी पढ़ने के लिए BTW, initWithNavigationBarClass कैसे कॉल करें ... stackoverflow.com/questions/22286166
Fattie

@ बहुत बढ़िया काम करते हैं यार! तो मैं पूरी तरह से एक टेबल व्यू कंट्रोलर पर काम कर रहा हूं सिवाय एक चीज के ... मुझे सबसे ऊपर लागू रिफ्रेश करने के लिए खींचतान है। नीचे खींचने और ताज़ा करने की कोशिश करने पर यह अजीब हो जाता है। इसके लिए कोई वर्कअराउंड हो सकता है?
एरिक्रिक

@ थुही ... यह भी कहता है कि मेरे पास एक दृश्य नियंत्रक था जहां मैंने नीचे एक तालिका दृश्य लागू किया है। मैं उस तालिका दृश्य पर हुक करना चाहता हूं जो काम करता है, हालांकि मेरा एक और दृष्टिकोण है जो तालिका दृश्य के ऊपर बैठा है जिसे मैं गायब करना चाहता हूं। यह कैसे काम कर सकता है?
एरिक्रिक

25

iOS8 में नेविगेशन बार को मुफ्त में छुपाने के गुण शामिल हैं। एक WWDC वीडियो है जो इसे प्रदर्शित करता है, "iOS 8 में कंट्रोलर एडवांसमेंट देखें"।

उदाहरण :

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/ के माध्यम से मिला


12

मेरे पास उसके लिए कुछ त्वरित और गंदा समाधान है। किसी भी गहराई से परीक्षण नहीं किया गया है, लेकिन यहाँ विचार है:

वह संपत्ति मेरे 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 के लिए है, यह बदसूरत है मुझे पता है लेकिन इसे प्राप्त करने का एक त्वरित तरीका है। किसी भी टिप्पणी / सुझाव का स्वागत है :)


12

यह 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;
}

10

यहाँ मेरा कार्यान्वयन है: SherginScrollableNavigationBar

मेरे दृष्टिकोण में मैं राज्य के KVOअवलोकन के लिए उपयोग कर रहा हूं UIScrollView, इसलिए एक प्रतिनिधि का उपयोग करने की कोई आवश्यकता नहीं है (और आप इस प्रतिनिधि का उपयोग किसी और चीज के लिए कर सकते हैं जो आपको चाहिए)।


FYI करें यह हमेशा सही ढंग से काम नहीं करता है। मैंने यह भी कोशिश की और यह तब तक काम करता है जब तक आप स्क्रॉलव्यू "उछल" नहीं रहे हैं। ऐसा लगता है कि उछाल भाग में केवीओ ट्रिगर नहीं है। ContentOffset के लिए प्रतिनिधि कॉल ट्रिगर है, हालांकि।
जॉरिस मैन्स

7

कृपया मेरे इस समाधान का प्रयास करें और मुझे बताएं कि यह पिछले उत्तरों की तरह अच्छा क्यों नहीं है।

- (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];
}

1
मैंने ऐसा ही कुछ किया है, और यह आसानी से सबसे अच्छा समाधान है। मैंने कई हैक और लाइब्रेरी की कोशिश की है, और यह एकमात्र ऐसा है जो iOS 9 के लिए काम करता है, जिसमें एक टेबल व्यू पूरे स्क्रीन को कवर नहीं करता है। कुडोस!
स्केनसेल 16

6

एक तरीका जो मैंने पूरा किया है वह निम्नलिखित है।

रजिस्टर आपके विचार नियंत्रक होने के लिए UIScrollViewDelegateअपने के UITableViewउदाहरण के लिए।

- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;

डी UIScrollViewDelegateविधियों के भीतर से आप नई सामग्री प्राप्त कर सकते हैंUINavigationBar

सबवे के अल्फा को सेट करना भी कुछ सीमा मूल्यों और उन कारकों के आधार पर किया जा सकता है जिन्हें आप सेट और गणना कर सकते हैं।

आशा करता हूँ की ये काम करेगा!


इसी तरह की पोस्ट यहां
डायना सुले

धन्यवाद डायना! मुझे संदेह था कि मुझे UIScrollViewDelegate के तरीकों को लागू करना पड़ सकता है लेकिन ऐसा लग रहा था कि यह थोड़ा ओवरकिल हो सकता है। एक बार जब मैं इस बात का पता लगाता हूं तो इसे पोस्ट कर देता हूं। चीयर्स!
एल मोसोसो

4

इव्बर्क के उत्तर के अलावा मैंने गैर कस्टम नेविगेशन बार पर अल्फा समस्या को ठीक करने के लिए और व्यूविलाडिसैपियर विधि में नेविगेशन बार को रीसेट करने के लिए निम्नलिखित को जोड़ा:

- (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];
}

क्या साक्षात्कार के माध्यम से लूपिंग के अलावा कोई अन्य तरीका है?
thisiscrazy4

जो मैं एक गैर कस्टम नेविगेशन बार पर बता सकता था, उसमें कुल 4 साक्षात्कार हैं: _UavavigationBarBackground, UINavigationItemView, UINavigationItemButtonView, और _UINavigationBarBackIndicatorView। लूप बहुत तेज है और मेरे ऐप के किसी भी प्रदर्शन को प्रभावित नहीं करता है।
ब्लू

चूंकि _UavavigationBarBackground हमेशा पहला सबव्यू लगता है कि आप सीधे बाकी को एक्सेस कर सकते हैं: ((UIView *) self.navigationController.navigationBar.subviews [1])। अल्फा = अल्फा
नीले रंग

4

मैं एक ऐसे समाधान की तलाश में था जो किसी भी शैली और किसी भी व्यवहार के लिए अनुमति दे। आप देखेंगे कि बार संघनक व्यवहार कई अलग-अलग ऐप में अलग है। और हां, जिस तरह से बार दिखता है वह ऐप्स के बीच बिल्कुल अलग है।

मैंने इस मुद्दे के लिए https://github.com/bryankeller/BLKFlexibleHeightBar/ के साथ एक समाधान बनाया

आप अपने स्वयं के व्यवहार के नियमों को निर्धारित कर सकते हैं कि बार कब और कैसे सिकुड़ता है और बढ़ता है, और आप बार-बार संघनन या बढ़ते हुए प्रतिक्रिया करने के लिए बार के उप-साक्षात्कार चाहते हैं कि आप कैसे परिभाषित कर सकते हैं।

मेरी परियोजना पर एक नज़र डालें यदि आप बहुत अधिक लचीलापन चाहते हैं तो आप किसी भी प्रकार के हेडर बार को सोच सकते हैं।


मैं इस customHeaderView में एक बटन कैसे जोड़ सकता हूं, जो मैं स्क्रॉल करने पर छिपाऊंगा। मुझे स्थिर बटन की आवश्यकता नहीं है। क्या यह संभव है? मैंने एक बटन को उप-भाग के रूप में बनाने की कोशिश की। लेकिन यह किसी भी स्पर्श को प्राप्त नहीं कर रहा है।
अभिमुर्लीधरन

3

मैं इस स्थिति का अनुकरण करने की कोशिश कर रहा था, जहां मुझे UITableView के बारे में बैठे एक स्वनिर्धारित हेडर की आवश्यकता थी। मैंने अपनी "नेविगेशन" पट्टी को रोल किया क्योंकि यह पृष्ठ पर अन्य सामानों के एक समूह के नीचे बैठता है और मैं चाहता था कि अनुभाग हेडर डिफ़ॉल्ट "डॉकिंग" व्यवहार का पालन करें। मुझे लगता है कि मैंने फेसबुक / इंस्टाग्राम / क्रोम / आदि में देखी जाने वाली शैली में एक अन्य वस्तु के साथ एक UITableView / UIScrollView को एक साथ समायोजित करने के लिए एक बहुत ही चतुर और रसीला तरीका पाया। क्षुधा।

मेरी .xib फ़ाइल में, मेरे पास मेरे घटक एक फ़्रीफ़ॉर्म दृश्य में लोड किए गए हैं: http://imgur.com/0z9yebJ (क्षमा करें, आपके पास इनलाइन छवियां नहीं हैं)

ध्यान दें कि, बाएं साइडबार में, मुख्य हेडर दृश्य के पीछे तालिका का आदेश दिया गया है। आप स्क्रीनशॉट से नहीं बता सकते हैं, लेकिन इसमें मुख्य हेडर दृश्य के समान वाई स्थिति है। चूंकि यह दृष्टि से बाहर है, UITableView पर 76 (मुख्य हेडर दृश्य की ऊंचाई) पर सेट की गई सामग्री।

UIScrollView के साथ एकरूपता में मुख्य हेडर दृश्य को स्लाइड करने के लिए, मैं कुछ गणना करने के लिए UIScrollViewDelegate के ScrollViewDidScroll तरीकों का उपयोग करता हूं और UIScrollView के कंटेंट को बदलने के साथ-साथ मुख्य हेडर व्यू के फ्रेम को बदलता हूं।

- (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);
    }
}

पहले अगर पहले की सीमा के बाहर हैं बयान बड़े कार्य करने का सबसे करता है, लेकिन मैं स्थितियों में, जहां उपयोगकर्ता जबरदस्ती खींच रहा है और प्रारंभिक contentOffset मूल्यों scrollViewDidScroll के लिए भेजा संभालने के लिए दो अन्य को शामिल करने के लिए किया था , तो बयान।

अंततः, यह मेरे लिए वास्तव में अच्छा काम कर रहा है। मैं अपनी परियोजनाओं को फूला हुआ उपवर्गों के साथ लोड करने से नफरत करता हूं। मैं यह नहीं बोल सकता कि क्या यह सबसे अच्छा समाधान प्रदर्शन-वार है (मैं स्क्रॉल कोड में कोई भी कोड डालने में हमेशा हिचकिचाता हूँ क्योंकि यह हर समय कहा जाता है), लेकिन कोड पदचिह्न वह सबसे छोटा है जो मैंने किसी में देखा है इस समस्या का हल और इसमें UITcrollView में एक UITableView का नामकरण शामिल नहीं है (Apple प्रलेखन में इस के खिलाफ सलाह देता है और UITableView पर घटनाओं को थोड़ा स्पर्श करता है)। आशा है कि यह किसी की मदद करता है!


3

HidingNavigationBar एक महान परियोजना है जो नेविगेशन बार और टैब बार कोछुपाता हैयदि आप चाहते हैं।

HidingNavigationBar निम्नलिखित दृश्य तत्वों को छिपाने / दिखाने का समर्थन करता है:

UINavigationBar

UINavigationBar और एक विस्तार UIView

UINavigationBar और एक UIToolbar

UINavigationBar और एक UITabBar

https://github.com/tristanhimmelman/HidingNavigationBar


2

मैंने GTScrollNavigationBar को लागू करने की कोशिश की, लेकिन मेरे ऐप को मुझे ऑटो लेआउट की बाधाओं को संशोधित करने की आवश्यकता थी। मैंने अपने कार्यान्वयन का एक उदाहरण गिटहब पर लागू करने का फैसला किया, अगर किसी और को ऑटो लेआउट के साथ ऐसा करना है। अन्य मुद्दों के साथ मेरे पास जो दूसरा मुद्दा था, वह यह है कि आप स्क्रॉल करते समय बनाए जाने वाले लंबन स्क्रॉलिंग प्रभाव से बचने के लिए लोग स्क्रॉल दृश्य की सीमा निर्धारित नहीं करते हैं और स्क्रॉल के आकार को एक साथ समायोजित करते हैं।

यदि आपको ऑटो लेआउट के साथ ऐसा करने की आवश्यकता है, तो JSCollapsingNavBarViewController देखें । मैंने दो संस्करणों को शामिल किया है, एक नेवी बार के साथ और दूसरा नेवी बार के नीचे एक सब-बार के साथ है जो नेवी बार को ढहने से पहले ढह जाता है।


1

मैंने इसे इस तरह से आजमाया, मुझे उम्मीद है कि यह मदद करेगा। बस प्रतिनिधि विधि में कोड को लागू करें और वांछित दृश्य / सबव्यू पर सेट करें

-(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
                }
        }

1

@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विधि के साथ अभी तक काम नहीं करता है, जब मेरे पास एक अपडेट होता है


0

ये सभी दृष्टिकोण अत्यधिक जटिल लगते हैं ... इसलिए स्वाभाविक रूप से, मैंने अपना खुद का निर्माण किया:

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
    }

}

navigationBar.height? scrollView.height? क्या आप frameसंपत्ति पर एक्सटेंशन का उपयोग करते हैं?
एली

0

मुझे ऑब्जेक्टिव-सी में दिए गए सभी उत्तर मिले। यह स्विफ्ट 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
    }
}

अल्फा को नेविगेशन आइटम पर सेट करने का तर्क @ वेनबर्कट उत्तर से कॉपी किया गया है और स्विफ्ट 3 में फिर से लिखा गया है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.