ন্যাভিগেশন বারকে ফেসবুকের আড়াল / প্রসারিত / চুক্তি করার অনুকরণ করুন


128

নতুন আইওএস 7 ফেসবুক আইফোন অ্যাপ্লিকেশনটিতে, ব্যবহারকারী navigationBarধীরে ধীরে নিজেকে স্ক্রোল করে এমন এক জায়গায় চলে যায় যেখানে এটি সম্পূর্ণরূপে অদৃশ্য হয়ে যায়। তারপরে ব্যবহারকারী যখন navigationBarআস্তে আস্তে স্ক্রল করে তখন ধীরে ধীরে নিজেকে দেখায়।

আপনি কীভাবে এই আচরণটি বাস্তবায়ন করবেন? আমি নিম্নলিখিত সমাধান সম্পর্কে সচেতন তবে এটি অবিলম্বে অদৃশ্য হয়ে যায় এবং এটি ব্যবহারকারীর স্ক্রোল অঙ্গভঙ্গির গতিতে মোটেই আবদ্ধ হয় না।

[navigationController setNavigationBarHidden: YES animated:YES];

আমি আশা করি এটি কোনও সদৃশ নয় কারণ "বিস্তৃত / চুক্তি" আচরণের বর্ণনা কীভাবে দেওয়া যায় তা আমি নিশ্চিত নই।


2
একই সমস্যা: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 21929220/… নোট করুন যে সাফারি আচরণের সাথে পুরোপুরি মিলানো অবিশ্বাস্যরকম কঠিন । সেখানে কিছু খুব, খুব জটিল নিয়ম আছে!
ফ্যাটি

1
আমার প্রকল্পে আমি এই প্রকল্পটি ব্যবহার করেছি এবং এটি ঠিক কাজ করেছে। এর ডকুমেন্টেশন একবার দেখুন।
ভিনিসিয়াস

github.com/bryankeller/BLKFlexibleHeightBar আপনাকে যা চান তা করতে দেয় এবং আরও অনেক কিছু করে। এটি আপনাকে সুনির্দিষ্টভাবে নির্দিষ্ট করতে দেয় যে বারটি সর্বাধিক হ্রাস করা থেকে সংক্ষিপ্তকরণের প্রতিটি পর্যায়ে কীভাবে দেখায়। এমনকি এটি আপনাকে নিজের আচরণগুলি নির্দিষ্ট করতে দেয়, যাতে এটি সাফারি, ফেসবুক বা অন্য কোনও অ্যাপের মতো কাজ করতে পারে।
blkhp19

আমি একটি ইউএনএভিগেশনবার ব্যবহার করি নি তবে পরিবর্তে একটি ইউভিউউ যুক্ত করেছি। নেভিগেশন বারের অনুলিপি করা দর্শনটি স্ক্রোলের ভিত্তিতে প্রসারিত হবে এবং চুক্তিবদ্ধ হবে। আমি টাস্কটি অর্জনের জন্য স্ক্রোলভিউডিডসক্রোল প্রতিনিধি পদ্ধতি ব্যবহার করেছি। আপনি নীচের উত্স কোডটি চেক এবং সম্পাদন
দীপক ঠাকুর

উত্তর:


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

এটি নিখুঁত পরিমাণের পরিবর্তে সর্বশেষ স্ক্রোল শতাংশের উপর ভিত্তি করে বারটিকে অবস্থান করে, যার ফলস্বরূপ ধীর বিবর্ণ হয়। আসল আচরণটি আরও ফেসবুকের মতো, তবে আমি এটিও পছন্দ করি।

দ্রষ্টব্য: এই সমাধানটি কেবল আইওএস 7+। আপনি যদি iOS এর পুরানো সংস্করণ সমর্থন করেন তবে প্রয়োজনীয় চেকগুলি যুক্ত করার বিষয়ে নিশ্চিত হন।


এইটা কাজ করে. আপনি যদি ধরেই নিচ্ছেন যে বার বোতাম আইটেমগুলির কাস্টম ভিউ রয়েছে। আমার ক্ষেত্রে আমার কাছে কাস্টম ভিউ নেই। সুতরাং উপরের বার বার বোতামগুলি আড়াল করে না। আমার কাছে মনে হয় @ নীরব সমাধান নববার আইটেমগুলি আড়াল করে দেখানোর জন্য আরও ভাল
ধনুশ

1
তুমি ঠিক. আমি এই সপ্তাহান্তে আরও সাধারণ সমাধান সন্ধান করতে পারি। পরিবর্তে ডিফল্ট আইটেমগুলিকে লক্ষ্য করা খুব কঠিন হওয়া উচিত নয় customView
ওয়েইন

আমি @ ধনুশের ইস্যুটিকে সম্বোধন করি নি তবে আমার একটি আপডেট আছে।
ওয়েইন

1
আমি স্টক বার বোতাম দিয়ে সমস্যাটি স্থির করেছি, তবে এই কোডটিতে আরও একটি সমস্যা রয়েছে। তাহলে ScrollViewএর contentSizeফ্রেম চেয়ে ছোট, সহচরী অ্যানিমেশন কাজ করে না। এছাড়াও নিশ্চিত করুন যে আপনি সমস্ত নেভিগেশন আইটেমের আলফাকে 1.0 এ পুনরায় সেট করেছেন viewDidDisappear
লেগোলেস

1
অটোলআউট ব্যবহার করা হয় এমন নিয়ন্ত্রণকারীদের উপর আপনি কি এই সমাধানটি পরীক্ষা করেছেন? আমার ক্ষেত্রে অটোলাউট ছাড়াই সবকিছু ঠিকঠাক চলছে, তবে এটি যখন চালু হয়, তখনও এটির নিচে কিছু অদ্ভুত সাদা ফালা দৃশ্যমান হয়
আলিয়াকসান্দ্র বি।

52

সম্পাদনা করুন: কেবলমাত্র আইওএস 8 এবং তারপরের জন্য।

আপনি ব্যবহার চেষ্টা করতে পারেন

self.navigationController.hidesBarsOnSwipe = YES;

আমার জন্য কাজ কর.

যদি আপনার কোডিংটি দ্রুতগতিতে হয় তবে আপনাকে এইভাবে ব্যবহার করতে হবে ( https://stackoverflow.com/a/27662702/2283308 থেকে )

navigationController?.hidesBarsOnSwipe = true

এটি আইওএস <8.0
পেটারে

1
পেট 60 টি0 যেমন বলেছে, এবং আমি ক্ষমা চেয়ে নিচ্ছি কেবল আইওএস 8 এবং ততোধিকের জন্য কাজ করে।
পেড্রো রোমো

4
এর পরে কীভাবে ফিরিয়ে আনবেন?
C0D3

আচরণটি কিছুটা অদ্ভুত। আমি খুব বেশি অন্বেষণ করিনি, তবে আপনি যদি দ্রুত স্ক্রোল করেন তবে এটি আবার দেখায়।
পেড্রো রোমিও

@ পেদ্রো রোমো দুর্দান্ত উত্তর।
গাগান_আইওএস

43

এখানে আরও একটি বাস্তবায়ন রয়েছে: TLYShyNavBar v1.0.0 প্রকাশিত!

প্রদত্ত সমাধানগুলি চেষ্টা করার পরে আমি নিজেই নিজেই সিদ্ধান্ত নেব এবং আমার কাছে তারা হয় খারাপ পারফর্ম করছে, এন্ট্রি এবং বয়লার প্লেট কোডের উচ্চ বাধা ছিল বা নাবারের নীচে এক্সটেনশন ভিউয়ের অভাব ছিল। এই উপাদানটি ব্যবহার করতে, আপনাকে যা করতে হবে তা হ'ল:

self.shyNavBarManager.scrollView = self.scrollView;

ওহ, এবং এটি আমাদের নিজস্ব অ্যাপ্লিকেশনটিতে পরীক্ষিত যুদ্ধ।


@ টিমআরনল্ড আপনার মতামতের জন্য ধন্যবাদ! আমি এই সমস্যাটি স্থির করেছি, পডটি এখনও আপডেট হয়নি> _ <এখনই এটি করবে! .. পড আপডেট হয়েছে!
মাজিওড

আমি আর একটি শট দেব! ধন্যবাদ!
টিম কেম্বার

আমি তোমার সাহায্য কে সাধুবাদ জানাই. দেখে মনে হচ্ছে আপনার প্রতিশ্রুতি সাহায্য করেছে। আমি এখনও একটি অদ্ভুত ইস্যু পেয়েছি যেখানে আমার ইউআইকোলিকেশনভিউটি এনএভি বার হওয়ায় সঠিকভাবে পুনরায় আকার দেওয়া হচ্ছে না, এবং এনএভি বারটি যেখানে ব্যবহৃত হবে সেগুলি কক্ষ সংগ্রহের সীমার বাইরে থাকায় সেগুলি উপরে চলে যাচ্ছে। আপনি কি জানেন যে এটি কেন ঘটছে?
টিম কেম্বার

4
চিত্রসমূহ: এই মন্তব্যটি লেখার পরে আমার সমাধানটি সেকেন্ডে খুঁজে পেয়েছে। আমাকে নিশ্চিত করতে extendedLayoutIncludesOpaqueBarsহয়েছিল যে YESআমারUICollectionViewController
টিম কেম্বার

@ টিমআরনল্ড এটি দুর্দান্ত! একই সমস্যাটির সাথে আরও একজন লোক ছিল এবং আশা করি আপনার সমাধান তাকে সহায়তা করবে।
মাজিওড

33

আপনি আমার জিটিএসক্রোলনাভিগেশন বারটি একবার দেখতে পারেন । ইউআইএসক্রোলভিউয়ের স্ক্রোলিংয়ের উপর ভিত্তি করে এটিকে স্ক্রোল করতে আমি ইউআইএনএভিগেশনবারকে সাবস্ক্ল্যাস করেছি।

দ্রষ্টব্য: আপনার যদি একটি OPAQUE নেভিগেশন বার থাকে, নেভিগেশন বারটি HIDDEN পাওয়ার সাথে সাথে স্ক্রলভিউটি অবশ্যই প্রসারিত করতে হবে। জিটিএসক্রোলনাভিগেশন বার ঠিক এটি করে। (ঠিক যেমন আইওএসে যেমন সাফারি।


BTW যে কেউ পড়ার জন্য, ঠিক কিভাবে initWithNavigationBarClass ... ডাকতে stackoverflow.com/questions/22286166
Fattie

@ তুই মহান কাজের মানুষ! সুতরাং আমি এই জিনিসটি পুরোপুরি পুরোপুরি একটি টেবিল ভিউ কন্ট্রোলারে কাজ করছি কেবলমাত্র এক জিনিস ছাড়া ... আমি শীর্ষে বাস্তবায়ন করা রিফ্রেশ করতে টানলাম। নীচে টানতে এবং রিফ্রেশ করার চেষ্টা করার সময় এটি অদ্ভুত হয়ে যায়। এটির জন্য কি কোনও কাজ হতে পারে?
অ্যারিক

@ থুই এছাড়াও ... আসুন আমি বলতে পারি যে আমার কাছে একটি ভিউ কন্ট্রোলার ছিল যেখানে আমি নীচে টেবিল ভিউ প্রয়োগ করেছি। আমি সেই টেবিল ভিউটিতে কাজ করতে চাই যা কাজ করে, তবে আমার কাছে অন্য মতামত রয়েছে যা টেবিলের দৃশ্যের উপরে বসে আছে যে আমিও অদৃশ্য হতে চাই। এই কাজ কিভাবে হতে পারে?
অ্যারিক

25

নেভিগেশন বারটি নিখরচায় রাখার জন্য আইওএস 8 এর বৈশিষ্ট্য অন্তর্ভুক্ত রয়েছে। এখানে একটি ডাব্লুডাব্লুডিসি ভিডিও রয়েছে যা এটি দেখায়, "আইওএস 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 / নেভিগেশন- বার-inteferences-ios8/ এর মাধ্যমে পাওয়া গেছে


12

আমার কাছে এর জন্য এক ধরণের দ্রুত এবং নোংরা সমাধান রয়েছে। কোনও গভীরতা পরীক্ষা করা হয়নি তবে এই ধারণাটি এখানে:

এই সম্পত্তিটি আমার ইউআইটিএবলভিউ কনট্রোলার ক্লাসের জন্য সমস্ত আইটেমটি নভবারে রাখবে

@property (strong, nonatomic) NSArray *navBarItems;

একই ইউআইটিএবল ভিউ কনট্রোলার ক্লাসে আমার রয়েছে:

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

এটি কেবল আইওএস> = 7 এর জন্য, এটি কুৎসিত আমি জানি তবে এটি অর্জনের একটি দ্রুত উপায়। কোন মন্তব্য / পরামর্শ স্বাগত :)


12

এটি আইওএস 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

এখানে আমার বাস্তবায়ন: শেরগিনস্ক্রোলযোগ্য নেভিগেশনবার

আমার পদ্ধতির মধ্যে আমি রাষ্ট্রের KVOপর্যবেক্ষণের জন্য ব্যবহার করছি UIScrollView, সুতরাং প্রতিনিধি ব্যবহার করার কোনও প্রয়োজন নেই (এবং আপনার এই প্রয়োজনের জন্য আপনি এই প্রতিনিধিটি ব্যবহার করতে পারেন)।


এফওয়াইআই এটি সর্বদা সঠিকভাবে কাজ করে না। আমি এটিও চেষ্টা করেছি এবং যতক্ষণ আপনি স্ক্রোলভিউটি "বাউন্স" করছেন না ততক্ষণ এটি কাজ করে। মনে হচ্ছে কেভিও বাউন্স অংশে চালু হয় না। কনটেন্টঅফসেটের জন্য ডেলিগেট কলটি ট্রিগার করা হয়েছে।
জোরিস মানস

7

আমার এই সমাধানটি চেষ্টা করে দেখুন এবং কেন আমাকে আগের উত্তরগুলির মতো ভাল নয় তা আমাকে জানান know

- (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
আমি এর অনুরূপ কিছু করেছি এবং এটি সহজেই সেরা সমাধান। আমি বেশ কয়েকটি হ্যাক এবং লাইব্রেরি চেষ্টা করেছি এবং এটি কেবলমাত্র আইওএস 9 এর জন্য কাজ করে যা টেবিল ভিউয়ের সাথে পুরো স্ক্রিনটি আবরণ করে না। যশ!
skensell

6

একটি উপায় যে আমি এটি সম্পাদন করেছি তা হল নীচে।

নিবন্ধন আপনার ভিউ নিয়ামক হতে UIScrollViewDelegateআপনার এর UITableViewউদাহরণস্বরূপ।

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

ডি UIScrollViewDelegateপদ্ধতির মধ্যে থেকে আপনি নতুন কন্টেন্ট অফসেট পেতে এবং আপনার অনুবাদ করতে পারেনUINavigationBar সেই অনুযায়ী উপর বা নীচে ।

সাবউভিউগুলির আলফা সেট করা কিছু থ্রোসোল্ড মান এবং ফ্যাক্টরগুলির উপর ভিত্তি করেও করা যেতে পারে যা আপনি সেট এবং গণনা করতে পারেন।

আশা করি এটা সাহায্য করবে!



ধন্যবাদ ডায়ানা! আমার সন্দেহ হয়েছিল যে আমাকে ইউআইএসক্রলভিউডেলিগেট পদ্ধতিগুলি প্রয়োগ করতে হবে তবে মনে হয়েছিল এটি কিছুটা বেশি মাত্রাতিরিক্ত হতে পারে। এই জিনিসটি একবার বের করে ফেললে আমি এটি পোস্ট করব। চিয়ার্স!
এল মোকোসো

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 টির মতামত রয়েছে: _উইন্যাভিগেশনবার্টব্যাকগ্রাউন্ড, ইউআইএনএভিগেশন আইটেমভিউ, ইউআইএনএভিগেশন আইটেম বাটনভিউ এবং _উইন্যাভিগেশনবারব্যাক ইন্ডিকেটরভিউ। লুপটি বেশ দ্রুত এবং এটি আমার অ্যাপ্লিকেশনটির কোনও কার্যকারিতা প্রভাবিত করে না বলে মনে হচ্ছে।
নাইলিস

যেহেতু _উইনএভিগেশনবারব্যাকগ্রাউন্ডটি সর্বদা প্রথম মতামত বলে মনে হয় আপনি কেবলমাত্র বাকীগুলিতে সরাসরি অ্যাক্সেস করতে পারতেন: ((ইউআইভিউ *) স্ব.নিভিগেশন কন্ট্রোলআরভিগেশন বার.সুভিউ [1])। আলফা = আলফা;
নীলনক

4

আমি এমন একটি সমাধান খুঁজছিলাম যা কোনও স্টাইল এবং যে কোনও আচরণের অনুমতি দেয়। আপনি লক্ষ্য করবেন যে বারে ঘনীভবন করার আচরণটি বিভিন্ন বিভিন্ন অ্যাপ্লিকেশনে আলাদা different এবং অবশ্যই, বারগুলি দেখতে অ্যাপ্লিকেশনগুলির মধ্যে সম্পূর্ণ ভিন্ন।

আমি এই সমস্যার সাথে একটি সমাধান তৈরি করেছি https://github.com/bryankeller/BLKFlexibleHeightBar/ দিয়ে তৈরি করেছি

কীভাবে বারটি সঙ্কুচিত হয় এবং কখন বৃদ্ধি পায় তা নিয়ন্ত্রণ করার জন্য আপনি নিজের আচরণের নিয়মগুলি নির্ধারণ করতে পারেন এবং বার সংক্ষিপ্তকরণ বা বাড়ার ক্ষেত্রে আপনি কীভাবে বারের মতামতগুলি প্রতিক্রিয়া দেখাতে চান তা আপনি ঠিক নির্ধারণ করতে পারেন।

আপনি যদি ভাবতে পারেন তবে যে কোনও ধরণের শিরোনাম বার তৈরি করতে যদি আপনি অনেক নমনীয়তা চান তবে আমার প্রকল্পটি একবার দেখুন।


আমি এই কাস্টমহাইডারভিউতে কীভাবে একটি বোতাম যুক্ত করতে পারি যা আমি যখন স্ক্রোল করি তখন আড়াল হয় I
অভিমুরলিধরণ

3

আমি এমন একটি পরিস্থিতিতে এই আচরণটি অনুকরণ করার চেষ্টা করছিলাম যেখানে আমার কোনও ইউআইটিবেল ভিউয়ের কাছে বসে একটি কাস্টমাইজড শিরোনাম প্রয়োজন। আমি আমার নিজের "নেভিগেশন" বারটি ঘুরিয়েছি কারণ এটি পৃষ্ঠায় অন্যান্য স্টাফগুলির একগুচ্ছের নীচে বসে আছে এবং আমি বিভাগের শিরোনামগুলি ডিফল্ট "ডকিং" আচরণ অনুসরণ করতে চাইছিলাম। আমি মনে করি যে আমি ইউআইটিএবলভি / ইউআইএসক্রোলভিউকে ফেসবুক / ইনস্টাগ্রাম / ক্রোম / ইত্যাদির মতো দেখা যায় এমন একটি স্টাইলে অন্য অবজেক্টের সাথে একত্রে সামঞ্জস্য করার জন্য বেশ চতুর এবং সংক্ষিপ্ত উপায় খুঁজে পেয়েছি। অ্যাপ্লিকেশন রয়েছে।

আমার .xib ফাইলে, আমি আমার উপাদানগুলি একটি ফ্রিফর্ম ভিউতে লোড করেছি: http://imgur.com/0z9yebJ (দুঃখিত, ছবিগুলির ইনলাইন করার জন্য রেপ নেই)

লক্ষ্য করুন যে, বাম সাইডবারে, টেবিলটি প্রধান শিরোনামের দৃশ্যের পিছনে অর্ডার করা হয়েছে। আপনি স্ক্রিনশট থেকে বলতে পারবেন না, তবে এটিতে প্রধান শিরোনামের মত একই y অবস্থান রয়েছে। যেহেতু এটি দৃষ্টিকোণ থেকে প্রসারিত, তাই ইউআইটিবেবল ভিউতে বিষয়বস্তু ইনসেট সম্পত্তি 76 ((মূল শিরোনামের দৃশ্যের উচ্চতা) সেট করে।

মূল হেডার ভিউ স্লাইডটি ইউআইএসক্রোলভিউয়ের সাথে একযোগে তৈরি করতে, আমি কিছু গণনা সম্পাদন করতে এবং ইউআইএসক্রোলভিউয়ের সামগ্রীবিন্যাসের পাশাপাশি প্রধান শিরোলেখের ফ্রেমের ফ্রেমগুলিকে পরিবর্তন করতে ইউআইএসক্রলভিউ ডেলিগেটের স্ক্রোলভিউডিডসক্রোল পদ্ধতি ব্যবহার করি।

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

প্রথম যদি বিবৃতিটি ভারী উত্তোলন বেশিরভাগ ক্ষেত্রে করে তবে আমি পরিস্থিতিগুলি পরিচালনা করতে অন্য দুটিকে অন্তর্ভুক্ত করতে হয়েছিল যেখানে ব্যবহারকারী জোর করে টেনে নিয়ে যাচ্ছেন এবং স্ক্রোলভিউডিডস্রোকলের কাছে প্রেরিত প্রাথমিক কন্টেন্টঅফসেট মানগুলি যদি প্রথম ব্যাপ্তির বাইরে থাকে তবে বিবৃতিটির ।

শেষ পর্যন্ত, এটি আমার জন্য সত্যই ভাল কাজ করছে। আমি আমার প্রকল্পগুলি স্ফীত সাবক্লাসগুলির একটি গুচ্ছ সহ লোড করা ঘৃণা করি। এটি সবচেয়ে ভাল সমাধান পারফরম্যান্স-ভিত্তিক কিনা তা নিয়ে আমি কথা বলতে পারছি না (যেহেতু এটি সর্বকালে বলা হয়ে থাকে তাই আমি কোনও কোড স্ক্রোলভিউডিসক্রোকলটিতে রাখতে সবসময়ই দ্বিধা বোধ করি), তবে কোড পাদদেশচিহ্নটি আমার মধ্যে দেখা সবচেয়ে ছোটতম এই সমস্যার সমাধান এবং এটি কোনও ইউআইএসক্রোলভিউতে কোনও ইউআইটিএলভিউতে বাসা বাঁধে না (অ্যাপল ডকুমেন্টেশনে এর বিরুদ্ধে পরামর্শ দেয় এবং স্পর্শ ইভেন্টগুলি ইউআইটিএবলভিউতে কিছুটা মজার থাকে)। আশা করি এটি কাউকে সাহায্য করবে!


3

হিডিংনাভিগেশন বার একটি দুর্দান্ত প্রকল্প যা আপনি চাইলে নেভিগেশন বার এবং ট্যাব বারকেআড়াল করে।

হিডিংন্যাভিগেশনবার নীচের দৃশ্যের উপাদানগুলি লুকিয়ে / দেখানো সমর্থন করে:

UINavigationBar

ইউআইএনএভিগেশনবার এবং একটি এক্সটেনশন ইউআইভিউ

ইউআইএনএভিগেশন বার এবং একটি ইউআইটিউলবার

ইউআইএনএভিগেশন বার এবং একটি ইউআইটিববার

https://github.com/tristanhimmelman/HidingNavigationBar


2

আমি জিটিএসক্রোলনাভিগেশনবার বাস্তবায়নের চেষ্টা করেছি কিন্তু আমার অ্যাপ্লিকেশনটিতে আমাকে স্বয়ংক্রিয় বিন্যাসের সীমাবদ্ধতাগুলি সংশোধন করতে হবে। অটো লেআউট দিয়ে অন্য কারও যদি এটি করতে হয় তবে আমি গিটহাবের উপরে আমার প্রয়োগের উদাহরণ স্থাপন করার সিদ্ধান্ত নিয়েছি। অন্যান্য বেশিরভাগ বাস্তবায়নের সাথে আমার যে অন্য সমস্যাটি ছিল তা হ'ল লোকেরা স্ক্রোল করার সময় আপনি যে প্যারালাক্স স্ক্রোলিং এফেক্টটি এড়ানোর জন্য এড়াতে স্ক্রোল ভিউয়ের সীমানা নির্ধারণ করেন না এবং একই সাথে স্ক্রোলভিউয়ের আকার সামঞ্জস্য করে।

আপনার যদি অটো লেআউট দিয়ে এটি করার প্রয়োজন হয় তবে জেএসক্লাপিংসিংভারবারভিউকন্ট্রোলারটি দেখুন । আমি দুটি সংস্করণ অন্তর্ভুক্ত করেছি, একটি কেবল এনএভি বারের সাথে এবং অন্যটি এনএভি বারের নীচে একটি সাব-বারের সাথে যা এনএভি বার ভেঙে যাওয়ার আগে ধসে পড়ে।


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

@ ইবার্বকের জবাবের একটি বর্ধিতাংশ ... নেভিগেশন বারের উত্স পরিবর্তন করার পরিবর্তে, নেভিগেশন বারের আকারকে প্রসারিত / সঙ্কুচিত করা দরকার।

- (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সম্পত্তিতে কোনও এক্সটেনশন ব্যবহার করেন ?
Ely

0

আমি উদ্দেশ্য-সিতে দেওয়া সমস্ত উত্তর পেয়েছি। এটি সুইফট 3 এ আমার উত্তর This এটি খুব জেনেরিক কোড এবং সরাসরি ব্যবহার করা যায়। এটি ইউআইএসক্রোলভিউ এবং ইউআইটিএবলভিউ উভয়ের সাথেই কাজ করে।

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-এ পুনরায় লিখিত হয়েছে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.