UITableView की तालिकाHeaderView का आकार कैसे बदलें?


103

मुझे tableHeaderView का आकार बदलने में परेशानी हो रही है। यह सरल काम नहीं करता है।

1) एक यूआईटेबल व्यू और उविव्यू (100 x 320 पीएक्स) बनाएं;

2) यूआईटीयू को यूआईटेबल व्यू के टेबलहैडर व्यू के रूप में सेट करें;

3) निर्माण और जाओ। सब कुछ ठीक है।

अब, मैं tableHeaderView का आकार बदलना चाहता हूं, इसलिए मैं यह कोड viewDidLoad में जोड़ता हूं:

self.tableView.autoresizesSubviews = YES;

self.tableView.tableHeaderView = myHeaderView;
self.tableView.tableFooterView = myFooterView;

CGRect newFrame = self.tableView.tableHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
self.tableView.tableHeaderView.frame = newFrame;

TableHeaderView की ऊंचाई 200 के साथ दिखाई देनी चाहिए, लेकिन 100 के साथ दिखाई देती है।

अगर मैं लिखूं:

self.tableView.autoresizesSubviews = YES;


CGRect newFrame = myHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
myHeaderView.frame = newFrame;


self.tableView.tableHeaderView = myHeaderView;
self.tableView.tableFooterView = myFooterView;

फिर यह 200 की ऊंचाई से शुरू होता है, जैसा मैं चाहता हूं। लेकिन मैं इसे रनटाइम में संशोधित करने में सक्षम होना चाहता हूं।

मैंने भी यह कोशिश की है, बिना सफलता के:

self.tableView.autoresizesSubviews = YES;

self.tableView.tableHeaderView = myHeaderView;
self.tableView.tableFooterView = myFooterView;

CGRect newFrame = self.tableView.tableHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
self.tableView.tableHeaderView.frame = newFrame;

[self.tableView.tableHeaderView setNeedsLayout];
[self.tableView.tableHeaderView setNeedsDisplay];
[self.tableView setNeedsLayout];
[self.tableView setNeedsDisplay];

यहाँ बिंदु यह है: हम रनटाइम में tableHeaderView का आकार कैसे बदल सकते हैं ???

क्या कोई ऐसा करने में सक्षम है?

धन्यवाद

iMe

जवाबों:


180

FYI करें: मैंने इसे टेबलहेडर व्यू को संशोधित करके और फिर से सेट करके काम करने के लिए प्राप्त किया है। इस स्थिति में, मैं टेबलहैडर व्यू के आकार को समायोजित कर रहा हूं जब UIWebView सबव्यू ने लोड करना समाप्त कर दिया है।

[webView sizeToFit];
CGRect newFrame = headerView.frame;
newFrame.size.height = newFrame.size.height + webView.frame.size.height;
headerView.frame = newFrame;
[self.tableView setTableHeaderView:headerView];

13
+1 यह मेरे लिए काम कर गया। आपके सेटव्यू को बदलने के बाद 'setTableHeaderView' को कॉल करना महत्वपूर्ण है। समस्या यह है, मेरा सबव्यू एक एनीमेशन के रूप में एक सेकंड में आकार बदलता है। अब मैं यह पता लगाने की कोशिश कर रहा हूं कि इसके साथ tableHeaderView को कैसे चेतन किया जाए।
एंड्रयू

1
बिल्कुल सही, धन्यवाद एक गुच्छा। मेरे लिए, यह उद्देश्य-सी में गुणों के कम वांछनीय गुणों में से एक का एक उदाहरण है। पता करने के लिए हमारे पास कोई रास्ता नहीं है (और कोई कारण नहीं हमें पता होना चाहिए) कि हेडर सेट करने से ऊंचाई को पुन: प्राप्त करने का दुष्प्रभाव होता है। हेडर की ऊंचाई को अपडेट करते समय इसे या तो स्वचालित रूप से करना चाहिए, या हमें [tableView recalculateHeaderHeight]हर बार की तरह कुछ कॉल करना चाहिए ।
जेकबॉक्सर 17

48
@ और मुझे पता है कि यह लगभग एक साल बहुत देर हो चुकी है, लेकिन बेहतर देर से फिर कभी नहीं: मैं setTableHeaderView:कॉल के साथ लपेटकर तालिका हेडर दृश्य की बदलती ऊंचाई को चेतन करने में सक्षम था [tableview beginUpdates]और[tableview endUpdates]
१०:११ पर jasongregori

2
@jasongregori आसान टिप्पणी जो आपने जोड़ी है - मैं देख रहा हूं कि एक ही तकनीक (शुरुआती यूपीडडेट्स) एक टेबलफुटेर व्यू के लिए ऊंचाई परिवर्तन को चेतन नहीं करती है जिस तरह से यह टेबलहेडर व्यू करता है। क्या आपने टेबलफुटर व्यू को चेतन करने का अच्छा तरीका समझ लिया है?
क्रि।

1
प्रभावशाली, यह तब काम करता है जब इसे एक यूआईवीईवाई एनीमेशन ब्लॉक के अंदर किया जाता है, हालांकि मुझे नहीं लगता कि यह उस मामले में बहुत कुशल है।
कर सकते हैं

12

यह उत्तर पुराना है और जाहिरा तौर पर iOS 7 और इसके बाद के संस्करण पर काम नहीं करता है।

मैं उसी समस्या में भाग गया, और मैं चेतन में परिवर्तन भी चाहता था, इसलिए मैंने अपने हेडर दृश्य के लिए UIView का उपवर्ग बनाया और इन विधियों को जोड़ा:

- (void)adjustTableHeaderHeight:(NSUInteger)newHeight{
    NSUInteger oldHeight = self.frame.size.height;
    NSInteger originChange = oldHeight - newHeight;

    [UIView beginAnimations:nil context:nil];

    [UIView setAnimationDuration:1.0f];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];

    self.frame = CGRectMake(self.frame.origin.x, 
                        self.frame.origin.y, 
                        self.frame.size.width, 
                        newHeight);

    for (UIView *view in [(UITableView *)self.superview subviews]) {
        if ([view isKindOfClass:[self class]]) {
            continue;
        }
        view.frame = CGRectMake(view.frame.origin.x, 
                            view.frame.origin.y - originChange, 
                            view.frame.size.width, 
                            view.frame.size.height);
    }

    [UIView commitAnimations];
}

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
    [(UITableView *)self.superview setTableHeaderView:self];
}

यह अनिवार्य रूप से UITableView के सभी साक्षात्कारों को एनिमेट करता है जो कॉलिंग क्लास के समान क्लास प्रकार नहीं हैं। एनीमेशन के अंत में, यह पर्यवेक्षण (UITableView) पर setTableHeaderView को कॉल करता है - इसके बिना उपयोगकर्ता स्क्रॉल करने के बाद UITableView सामग्री अगली बार वापस आ जाएगी। इस पर अब तक केवल एक ही सीमा मुझे मिली है, यदि उपयोगकर्ता UITableView को स्क्रॉल करने का प्रयास करता है, जबकि एनीमेशन हो रहा है, तो स्क्रॉल चेतन होगा जैसे कि हेडर दृश्य को आकार नहीं दिया गया है (यदि एनीमेशन है तो कोई बड़ी बात नहीं) शीघ्र)।


पूरी तरह से काम करता है, एनीमेशन को हटा दिया क्योंकि मुझे इसकी आवश्यकता नहीं थी।
जिहो कांग


1
WTF? आप यूआईटेबल व्यू के इंटर्न के साथ इतना गड़बड़ कर रहे हैं कि आपको वास्तव में आश्चर्य नहीं होना चाहिए कि यह नए आईओएस संस्करणों में काम नहीं करता है ...;)
डैनियल रिंसर

10

यदि आप सशर्त रूप से परिवर्तनों को चेतन करना चाहते हैं, तो आप निम्न कार्य कर सकते हैं:

- (void) showHeader:(BOOL)show animated:(BOOL)animated{

    CGRect closedFrame = CGRectMake(0, 0, self.view.frame.size.width, 0);
    CGRect newFrame = show?self.initialFrame:closedFrame;

    if(animated){
        // The UIView animation block handles the animation of our header view
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:0.3];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

        // beginUpdates and endUpdates trigger the animation of our cells
        [self.tableView beginUpdates];
    }

    self.headerView.frame = newFrame;
    [self.tableView setTableHeaderView:self.headerView];

    if(animated){
        [self.tableView endUpdates];
        [UIView commitAnimations];
    }
}

कृपया ध्यान दें कि एनीमेशन दो गुना है:

  1. नीचे दी गई कोशिकाओं का एनीमेशन tableHeaderView। यह प्रयोग किया जाता है beginUpdatesऔरendUpdates
  2. वास्तविक हेडर दृश्य का एनीमेशन। यह एक UIViewएनीमेशन ब्लॉक का उपयोग करके किया जाता है ।

उन दो एनिमेशन को सिंक्रोनाइज़ animationCurveकरने के लिए UIViewAnimationCurveEaseInOutऔर उस अवधि के लिए सेट करना होगा 0.3, जो यूआईटेबल व्यू का उपयोग करता है।

अपडेट करें

मैंने गिहब पर एक एक्सकोड प्रोजेक्ट बनाया, जो यह करता है। अगले प्रोजेक्ट ResizeTableHeaderViewAnimatedको देखें

स्क्रीनशॉट


2
यह तकनीक काम करती है, लेकिन यह अनुभाग हेडर के साथ टेबल व्यू के लिए काम नहीं करती है। जब आप अपडेट अपडेट / समाप्ति अपडेट का उपयोग करते हैं तो यह डुप्लिकेट सेक्शन हेडर छोड़कर एनीमेशन ब्लॉक में हस्तक्षेप करता है।
ब्लूफिश

9

मुझे लगता है कि यह काम करना चाहिए अगर आप सिर्फ myHeaderView की ऊंचाई निर्धारित करते हैं जैसे:

CGRect newFrame = myHeaderView.frame;
newFrame.size.height = newFrame.size.height + 100;
myHeaderView.frame = newFrame;

self.tableView.tableHeaderView = myHeaderView;

यह वास्तव में काम करता है, लेकिन केवल तभी जब viewDidLayoutSubviews में इस्तेमाल किया
KoCMoHaBTa

6

IOS 7 तक ऊपर @garrettmoon समाधान का उपयोग किया गया।
यहां @ grettmoon के आधार पर एक अद्यतन समाधान है:

- (void)adjustTableHeaderHeight:(NSUInteger)newHeight animated:(BOOL)animated {

    [UIView beginAnimations:nil context:nil];

    [UIView setAnimationDuration:[CATransaction animationDuration]];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];

    self.frame = CGRectMake(self.frame.origin.x,
                        self.frame.origin.y,
                        self.frame.size.width,
                        newHeight);

    [(UITableView *)self.superview setTableHeaderView:self];

    [UIView commitAnimations];
}

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{
    [(UITableView *)self.superview setTableHeaderView:self];
}

5

इसने मेरे लिए iOS 7 और 8 पर काम किया। यह कोड टेबल व्यू कंट्रोलर पर चल रहा है।

[UIView animateWithDuration:0.3 animations:^{
    CGRect oldFrame = self.headerView.frame;
    self.headerView.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, oldFrame.size.width, newHeight);
    [self.tableView setTableHeaderView:self.headerView];
}];

4

इसकी वजह है tableHeaderView का सेटर।

आपको TableHeaderView सेट करने से पहले UIView ऊंचाई सेट करनी होगी। (अगर ऐप्पल ने इस ढांचे को खोला तो बहुत आसान होगा ...)


4

IOS 9 और उसके नीचे, tableHeaderViewइसे आकार देने के बाद पुनः लेआउट नहीं होगा। यह समस्या iOS 10 में हल हो गई है।

इस समस्या को हल करने के लिए, बस इसे निम्नलिखित कोड के साथ करें:

self.tableView.tableHeaderView = self.tableView.tableHeaderView;

2

IOS 9.x पर, यह viewDidLoadठीक काम करता है:

var frame = headerView.frame
frame.size.height = 11  // New size
headerView.frame = frame

headerViewके रूप में घोषित किया गया है @IBOutlet var headerView: UIView!और स्टोरीबोर्ड पर जुड़ा हुआ है, जहां इसे टेबल व्यू के शीर्ष पर रखा गया है, टेबलहेडर व्यू के रूप में कार्य करने के लिए।


2

यह केवल तब होता है जब आप ऑटो-लेआउट का उपयोग करते हैं और translatesAutoresizingMaskIntoConstraints = falseकस्टम हेडर दृश्य पर सेट होते हैं।

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

  1. कस्टम हेडर / फुटर व्यू के लेआउट को कॉन्फ़िगर करें (साक्षात्कार)
  2. आह्वान invalidateIntrinsicContentSize()
  3. आह्वान tableView.setNeedsLayout()औरtableView.layoutIfNeeded()

फिर UITableViewजैसा आप चाहते हैं वैसा ही हैडर / फुटर अपडेट किया जाएगा। दृश्य शून्य या रीसेट सेट करने की कोई आवश्यकता नहीं है।

एक बात सच के लिए दिलचस्प UITableView.tableHeaderViewया .tableFooterViewवह यह है कि UIStackViewढीला अपने प्रबंधन करने की क्षमता arrangedSubviews। यदि आप UIStackViewtableHeaderView या tableFooterView के रूप में उपयोग करना चाहते हैं , तो आपको स्टैक व्यू को एक UIViewऔर ओवरराइड UIViewके एस में एम्बेड करना होगा intrinsicContentSize


2

स्विफ्ट 5 टेस्टेड कोड के लिए

override func viewDidLayoutSubviews() {
      super.viewDidLayoutSubviews()

        guard let headerView = self.tblProfile.tableHeaderView else {
            return
        }

        let size = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)

        if headerView.frame.size.height != size.height {
            headerView.frame.size.height = size.height
            self.tblProfile.tableHeaderView = headerView
            self.tblProfile.layoutIfNeeded()
        }
    }

नोट: आपको सभी सबव्यू की बाधाओं को शीर्ष, नीचे, अग्रणी, अनुगामी बनाने की आवश्यकता है। तो यह पूरे आवश्यक आकार प्राप्त करेगा।

संदर्भ से लिया गया: https://useyourloaf.com/blog/variable-height-table-view-header/


1

स्थापना ऊंचाई हैडर दृश्य संपत्ति के लिए tableView.tableHeaderViewमें viewDidLoadनहीं लगता है, काम करते हैं, शीर्ष लेख दृश्य ऊंचाई अभी भी अपेक्षा के अनुरूप नहीं बदल।

कई कोशिशों के बाद इस मुद्दे पर लड़ने के बाद। मैंने पाया कि, आप शीर्ष लेख को - (void)didMoveToParentViewController:(UIViewController *)parentविधि के अंदर तर्क बनाने के दृश्य को बढ़ाकर बदल सकते हैं ।

तो उदाहरण कोड इस तरह दिखेगा:

- (void)didMoveToParentViewController:(UIViewController *)parent {
    [super didMoveToParentViewController:parent];

    if ( _tableView.tableHeaderView == nil ) {
        UIView *header = [[[UINib nibWithNibName:@"your header view" bundle:nil] instantiateWithOwner:self options:nil] firstObject];

        header.frame = CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), HeaderViewHeight);

        [_tableView setTableHeaderView:header];
    }
}

0

मैंने पाया कि एक UIView का initWithFrame इनिशियलाइज़र मेरे द्वारा पास की गई रीले को ठीक से सम्मानित नहीं करता है। इसलिए, मैंने निम्नलिखित कार्य किया जो पूरी तरह से काम करता है:

 - (id)initWithFrame:(CGRect)aRect {

    CGRect frame = [[UIScreen mainScreen] applicationFrame];

    if ((self = [super initWithFrame:CGRectZero])) {

        // Ugly initialization behavior - initWithFrame will not properly honor the frame we pass
        self.frame = CGRectMake(0, 0, frame.size.width, 200);

        // ...
    }
}

इसका फायदा यह है कि आपके व्यू कोड में बेहतर एनकैप्सुलेटेड है।


इससे फ्रेम प्राप्त करना UIScreenएक बुरा विचार है, आप अपने दृष्टिकोण का फिर से उपयोग कैसे करेंगे?
जोरावर

0

मैंने टैप करते समय समग्र स्क्रीन पर विस्तार करने के लिए तालिका के शीर्ष लेख के एनिमेटेड ऊंचाई परिवर्तन को लागू किया है। हालाँकि, कोड अन्य मामलों में मदद कर सकता है:

// Swift
@IBAction func tapped(sender: UITapGestureRecognizer) {

    self.tableView.beginUpdates()       // Required to update cells. 

    // Collapse table header to original height
    if isHeaderExpandedToFullScreen {   

        UIView.animateWithDuration(0.5, animations: { () -> Void in
            self.scrollView.frame.size.height = 110   // original height in my case is 110
        })

    }
    // Expand table header to overall screen            
    else {      
        let screenSize = self.view.frame           // "screen" size

        UIView.animateWithDuration(0.5, animations: { () -> Void in
            self.scrollView.frame.size.height = screenSize.height
        })
    }

    self.tableView.endUpdates()  // Required to update cells. 

    isHeaderExpandedToFullScreen= !isHeaderExpandedToFullScreen  // Toggle
}

0

UITableView हेडर का आकार बदलना - स्कोप बार के साथ UISearchBar

मैं एक चाहते थे UITableViewएक साथ UISearchBarतो मैं एक पदानुक्रम है मेज पर हेडर के रूप में है कि इस तरह दिखता है

UITableView
  |
  |--> UIView
  |     |--> UISearchBar
  |
  |--> UITableViewCells

UISearchBarDelegate तरीके

जैसा कि कहीं और कहा गया है, यदि आप इसे बदलने के बादTTableViewHeader सेट नहीं करते हैं, तो कुछ भी नहीं होगा।

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
    searchBar.showsScopeBar = YES;
    [UIView animateWithDuration:0.2f animations:^{
        [searchBar sizeToFit];
        CGFloat height = CGRectGetHeight(searchBar.frame);

        CGRect frame = self.tableView.tableHeaderView.frame;
        frame.size.height = height;
        self.tableHeaderView.frame = frame;
        self.tableView.tableHeaderView = self.tableHeaderView;
    }];

    [searchBar setShowsCancelButton:YES animated:YES];
    return YES;
}

- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
    searchBar.showsScopeBar = NO;
    [UIView animateWithDuration:0.f animations:^{
        [searchBar sizeToFit];

        CGFloat height = CGRectGetHeight(searchBar.frame);

        CGRect frame = self.tableView.tableHeaderView.frame;
        frame.size.height = height;
        self.tableHeaderView.frame = frame;
        self.tableView.tableHeaderView = self.tableHeaderView;
    }];

    [searchBar setShowsCancelButton:NO animated:YES];
    return YES;
}

0

यदि कस्टम हेडर व्यू को ऑटोलॉययूट का उपयोग करके बनाया गया है और हैडरव्यू को वेब-लिंच या इसी तरह के आलसी कार्य के बाद अपडेट करने की आवश्यकता है। इसके बाद iOS-Swift में मैंने ऐसा किया और अपने हेडर व्यू को bellow कोड का उपयोग करके अपडेट किया:

//to reload your cell data
self.tableView.reloadData()
dispatch_async(dispatch_get_main_queue(),{
// this is needed to update a specific tableview's headerview layout on main queue otherwise it's won't update perfectly cause reloaddata() is called
  self.tableView.beginUpdates()
  self.tableView.endUpdates()
} 

0

जाहिर है, अब तक Apple को tableHeaderView और tableFooterView के लिए UITableViewAutomaticDimension लागू करना चाहिए था ...

निम्नलिखित मेरे लिए लेआउट गर्भनिरोधक का उपयोग कर काम करता है:

CGSize   s  = [ self  systemLayoutSizeFittingSize : UILayoutFittingCompressedSize ];
CGRect   f  = [ self  frame ];

f.size   = s;

[ self  setFrame : f ];

0

यदि आपका tableHeaderView एक सामग्री समायोज्य webView है, तो आप कोशिश कर सकते हैं:

[self.webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    self.webView.height = self.webView.scrollView.contentSize.height;
    self.tableView.tableHeaderView = self.webView;
}

मैंने इसे iOS9 और iOS11 पर परीक्षण किया, अच्छी तरह से काम किया।


-3

क्या आपने [self.tableView reloadData]ऊंचाई बदलने के बाद कोशिश की ?


1
यह TableHeaderView के बारे में है, जो एक स्थिर दृश्य है। - [UITableView reloadData]केवल गतिशील विचारों (कोशिकाओं) के लिए अभिप्रेत है और यह भी कि आप स्पष्ट रूप से सोचा था कि अनुभागहेडर्स ;)
जूलियन एफ। वेनर्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.