ইউআইটিএবলভিউয়ের টেবিলহাইডারভিউ দিয়ে অটলাউট ব্যবহার করা কি সম্ভব?


100

যেহেতু আমি আবিষ্কার AutoLayoutকরেছি যে আমি এটি সর্বত্র ব্যবহার করি, এখন আমি এটি দিয়ে এটি ব্যবহার করার চেষ্টা করছি tableHeaderView

আমি একটি তৈরি subclassএর UIViewযোগ সবকিছু (লেবেল ইত্যাদি ...) আমি তাদের সীমাবদ্ধতার সঙ্গে চেয়েছিলেন তারপর আমি এই যোগ CustomViewকরার UITableView' tableHeaderView

সবকিছু ছাড়া শুধু কাজ করে জরিমানা UITableViewসবসময় প্রদর্শন উপরেCustomView দ্বারা উপরে আমি বলতে চাচ্ছি CustomViewহয় অধীনেUITableView তাই এটি দেখা যায় না!

মনে হচ্ছে যে কোন ব্যাপার আমি কি, heightএর UITableView' tableHeaderViewহয় সবসময় 0 (তাই প্রস্থ, x এবং y যায়)।

আমার প্রশ্ন: ফ্রেমটি ম্যানুয়ালি সেট না করে এটি সম্পাদন করা কি আদৌ সম্ভব ?

সম্পাদনা: যে CustomView' subviewআমি ব্যবহার করছি তার মধ্যে এই বাধা রয়েছে:

_title = [[UILabel alloc]init];
_title.text = @"Title";
[self addSubview:_title];
[_title keep:[KeepTopInset rules:@[[KeepEqual must:5]]]]; // title has to stay at least 5 away from the supperview Top
[_title keep:[KeepRightInset rules:@[[KeepMin must:5]]]];
[_title keep:[KeepLeftInset rules:@[[KeepMin must:5]]]];
[_title keep:[KeepBottomInset rules:@[[KeepMin must:5]]]];

আমি একটি সহজ লাইব্রেরি 'কিপলআউট' ব্যবহার করছি কারণ লেখার সীমাবদ্ধতাগুলি ম্যানুয়ালি চিরতরে লাগে এবং একক প্রতিবন্ধকতার জন্য অনেকগুলি লাইন অতিক্রম করে তবে পদ্ধতিগুলি স্ব-ব্যাখ্যা করে।

এবং UITableViewএই বাধা আছে:

_tableView = [[UITableView alloc]init];
_tableView.translatesAutoresizingMaskIntoConstraints = NO;
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.backgroundColor = [UIColor clearColor];
[self.view addSubview:_tableView];
[_tableView keep:[KeepTopInset rules:@[[KeepEqual must:0]]]];// These 4 constraints make the UITableView stays 0 away from the superview top left right and bottom.
[_tableView keep:[KeepLeftInset rules:@[[KeepEqual must:0]]]];
[_tableView keep:[KeepRightInset rules:@[[KeepEqual must:0]]]];
[_tableView keep:[KeepBottomInset rules:@[[KeepEqual must:0]]]];

_detailsView = [[CustomView alloc]init];
_tableView.tableHeaderView = _detailsView;

আমি সরাসরি আমাকে কিছু বাধা নির্ধারণ করতে হবে কিনা জানি না CustomView, আমি মনে করি কাস্টমভিউয়ের উচ্চতা এতে UILabel"শিরোনাম" এর সীমাবদ্ধতা দ্বারা নির্ধারিত হয় ।

সম্পাদনা 2: অন্য তদন্তের পরে মনে হয় কাস্টমভিউয়ের উচ্চতা এবং প্রস্থটি সঠিকভাবে গণনা করা হয়েছে, তবে কাস্টমভিউয়ের শীর্ষটি এখনও ইউআইটিএবলভিউয়ের শীর্ষের তুলনায় একই স্তরে রয়েছে এবং আমি স্ক্রোল করলে তারা একসাথে চলে যায় move


হ্যা এটা সম্ভব. আপনি যে কোডটি ব্যবহার করছেন তা কি আপনি প্রদর্শন করতে পারেন? হেডার ভিউতে আপনি কী কী প্রতিবন্ধকতা স্থাপন করেছেন তা না জেনে পরামর্শ দেওয়া শক্ত।
jrturton

একটি সহজ উপায় আপনি এই কাজ করা সম্ভব যে দৃশ্য যোগ করতে হয় আইবি tableView..just একই দৃশ্য tableview ধারণকারী দেখুন তৈরি করুন এবং টানুন এটা টেবিলের করতে।
মেরিয়াম কে।

আমি যতটুকু সম্ভব আইবি এড়াতে চেষ্টা করছি, এখন পর্যন্ত আমাকে এটি ব্যবহার করতে হবে না, যদি আমি এটি কাজ না করতে পারি তবে আমি আইবি

4
অ্যাপল যখন বিকাশকারীদের অটোলেআউট আসে তখন আইবি ব্যবহার করতে পরামর্শ দেয়। এটি সত্যই প্রচুর অসঙ্গতিজনিত সমস্যা এড়াতে সহায়তা করে।
মেরিয়াম কে।

আসল সম্পূর্ণ
অটোলেআউট

উত্তর:


136

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

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.header = [[SCAMessageView alloc] init];
    self.header.titleLabel.text = @"Warning";
    self.header.subtitleLabel.text = @"This is a message with enough text to span multiple lines. This text is set at runtime and might be short or long.";

    //set the tableHeaderView so that the required height can be determined
    self.tableView.tableHeaderView = self.header;
    [self.header setNeedsLayout];
    [self.header layoutIfNeeded];
    CGFloat height = [self.header systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    //update the header's frame and set it again
    CGRect headerFrame = self.header.frame;
    headerFrame.size.height = height;
    self.header.frame = headerFrame;
    self.tableView.tableHeaderView = self.header;
}

আপনার যদি মাল্টি-লাইন লেবেল থাকে, তবে এটি প্রতিটি লেবেলের পছন্দসই ম্যাক্স লেআউটউইথ প্রস্থকে কাস্টম ভিউ সেটিংসের উপর নির্ভর করে:

- (void)layoutSubviews
{
    [super layoutSubviews];

    self.titleLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.titleLabel.frame);
    self.subtitleLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.subtitleLabel.frame);
}

বা সম্ভবত আরও সাধারণভাবে:

override func layoutSubviews() {
    super.layoutSubviews()  
    for view in subviews {
        guard let label = view as? UILabel where label.numberOfLines == 0 else { continue }
        label.preferredMaxLayoutWidth = CGRectGetWidth(label.frame)
    }
}

জানুয়ারী 2015 আপডেট করুন

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

tableView.tableHeaderView = header
header.setNeedsLayout()
header.layoutIfNeeded()
header.frame.size = header.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
tableView.tableHeaderView = header

আমি এটি ইউআইটিএবলভিউতে একটি এক্সটেনশনে স্থানান্তরিত করতে দরকারী বলে মনে করেছি:

extension UITableView {
    //set the tableHeaderView so that the required height can be determined, update the header's frame and set it again
    func setAndLayoutTableHeaderView(header: UIView) {
        self.tableHeaderView = header
        header.setNeedsLayout()
        header.layoutIfNeeded()
        header.frame.size = header.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
        self.tableHeaderView = header
    }
}

ব্যবহার:

let header = SCAMessageView()
header.titleLabel.text = "Warning"
header.subtitleLabel.text = "Warning message here."
tableView.setAndLayoutTableHeaderView(header)

8
ব্যবহারের বিকল্প preferredMaxLayoutWidthহ'ল ব্যবহারের পূর্বে শিরোনাম দর্শনে প্রস্থের সীমাবদ্ধতা (টেবিল দর্শনের প্রস্থের সমান) যুক্ত করা হচ্ছে systemLayoutSizeFittingSize:
বেঞ্জহান

4
দ্রষ্টব্য: যদি আপনি অনুভব করছেন যে শিরোনামটি প্রথম কক্ষগুলির উপরে রয়েছে, তবে আপনি শিরোনামের সম্পত্তিটি পুনরায় সেট করতে ভুলে গেছেনself.tableView.tableHeaderView
লাসজলো

9
প্রায়শই এটি আমাকে বিস্মিত করে যে এর মতো সম্পূর্ণ তুচ্ছ কিছু করা কতটা জটিল।
টাইলারজেমস

5
দ্রষ্টব্য: যদি আপনাকে টেবিলভিউ হিসাবে সঠিক প্রস্থের প্রয়োজন হয়, আপনার প্রয়োজনীয় অনুভূমিক অগ্রাধিকার সহ উচ্চতা পাওয়া উচিতlet height = header.systemLayoutSizeFittingSize(CGSizeMake(CGRectGetWidth(self.bounds), 0), withHorizontalFittingPriority: UILayoutPriorityRequired, verticalFittingPriority: UILayoutPriorityFittingSizeLevel).height
JakubKnejzlik

4
জাস্ট ইউজ header.setNeedsLayout() header.layoutIfNeeded() header.frame.size = header.systemLayoutSizeFitting(UILayoutFittingCompressedSize) self.tableHeaderView = headerআইওএস 10.2 এ কাজ করবে
কেসং জি

24

সীমাবদ্ধতা (কোডে) ব্যবহার করে আমি হেডার ভিউ যুক্ত করতে পারিনি। আমি যদি আমার দর্শনটিকে প্রস্থ এবং / অথবা উচ্চতার সীমাবদ্ধতা দিই, তবে বার্তাটি দিয়ে ক্র্যাশ পেয়েছি:

 "terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super."

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

প্রস্থটি স্বয়ংক্রিয়ভাবে টেবিল দর্শনের প্রস্থ হয়, আপনাকে কেবলমাত্র সেট করতে হবে উচ্চতা - মূল মানগুলি অগ্রাহ্য করা হয়, সুতরাং আপনি তাদের জন্য কী রেখেছেন তাতে কিছু আসে যায় না। উদাহরণস্বরূপ, এটি ভাল কাজ করেছে (রেক্টরের জন্য 0,0,0,80 হিসাবে):

UIView *headerview = [[UIView alloc] initWithFrame:CGRectMake(1000,1000, 0, 80)];
headerview.backgroundColor = [UIColor yellowColor];
self.tableView.tableHeaderView = headerview;

আমি যে ব্যতিক্রম খুব কাজ করতেন কিন্তু অনেক UITableView একটি বিভাগ যোগ করার এটি সংশোধন করা হয়েছে আমি যে উত্তর এটা পাওয়া গেছে: stackoverflow.com/questions/12610783/...
ItsASecret

আপনার পরামর্শ অনুসারে আমি এখনও চেষ্টা করে যাচ্ছি, কিন্তু কাল সকালে, আমি 1:34 পূর্বাহ্নে শুতে যাচ্ছি, উত্তর দেওয়ার জন্য সময় দেওয়ার জন্য আপনাকে অনেক ধন্যবাদ! (তবে আমি সত্যিই কোনও উচ্চতা উল্লেখ করতে চাই না, আমি এটি কাস্টমভিউতে লেবেলে যে প্রতিবন্ধকতাগুলি রেখেছি তা দ্বারা গণনা করতে চাই)
ItASecret

আমি এটি চেষ্টা করেছি এবং হ্যাঁ ফ্রেমটি কাজ করে যাচ্ছে তবে আমি ফ্রেমটি সেট করা এড়ানোর জন্য একটি উপায় খুঁজছিলাম, আমি খুঁজতে থাকব এবং যদি আমি আর কিছুই না পাই তবে আমি আপনার উত্তর গ্রহণ করব
ItASecret

4
অ্যাডেড শিরোনাম দর্শনটি থাকলে আমি এই ব্যতিক্রমটি পাই (বর্তমানে .1.১ পরীক্ষা করছি) translatesAutoresizingMaskIntoConstraints = NO। অনুবাদটি চালু করা ত্রুটি প্রতিরোধ করে - আমার সন্দেহ UITableViewহয় 7.1 এর হিসাবে এটির শিরোনামের দৃশ্যটি স্বয়ংচালিত করার চেষ্টা করে না এবং ফ্রেম প্রাক-সেট সহ কিছু চায়।
বেঞ্জহান

17

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

func loadHeaderView () {
        guard let headerView = Bundle.main.loadNibNamed("CourseSearchHeader", owner: self, options: nil)?[0] as? UIView else {
            return
        }
        headerView.autoresizingMask = .flexibleWidth
        headerView.translatesAutoresizingMaskIntoConstraints = true
        tableView.tableHeaderView = headerView
    }

এটি মাল্টি-লাইন লেবেল সহ গতিশীল উচ্চতার শিরোনাম সহ আইওএস 11 এও আমাদের জন্য কাজ করেছে।
বেন স্কিমারান

4
আপনি অবশ্যই আইবিতে নমনীয় হাইট-অটোরাইজিং-অপশনটি সরাতে পারেন।
d4Rk

আমি আমার টেবিলফুটারভিউয়ের উচ্চতা (একটি এক্সিব / নিব মাধ্যমে) সেট করার চেষ্টা করেছি এবং ফ্রেম, উচ্চতা, লেআউটআইফনেড () ইত্যাদি নির্ধারণে সাফল্য পাচ্ছিলাম না তবে এই সমাধানটি শেষ পর্যন্ত আমাকে এটি সেট করার অনুমতি দেয়।
ভিকজিলা

কোনও এক্সিবিল ফাইলে পুরো দর্শনে উচ্চতার সীমাবদ্ধতা সেট করতে ভুলবেন না।
ডেনিস কুতলুবায়েভ

6

আর একটি সমাধান হ'ল শিরোনামের প্রদর্শনটি পরবর্তী মূল থ্রেড কলটিতে প্রেরণ করা:

- (void)viewDidLoad {
    [super viewDidLoad];

    // ....

    dispatch_async(dispatch_get_main_queue(), ^{
        _profileView = [[MyView alloc] initWithNib:@"MyView.xib"];
        self.tableView.tableHeaderView = self.profileView;
    });
}

দ্রষ্টব্য: লোড ভিউটির নির্দিষ্ট উচ্চতা থাকলে এটি বাগটি ঠিক করে। আমি চেষ্টা করিনি যখন শিরোনামের উচ্চতা কেবল তার সামগ্রীর উপর নির্ভর করে।

সম্পাদনা:

আপনি এই ফাংশনটি প্রয়োগ করে এবং এটিকে কল করে এই সমস্যার একটি ক্লিনার সমাধান খুঁজে পেতে পারেনviewDidLayoutSubviews

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    [self sizeHeaderToFit];
}

4
@ টাসলাস্লোলো অটোলেআউট tableHeaderViewসহ এক ধরণের বগি। এই মত কিছু workaround আছে। কিন্তু যেহেতু আমি এই লিখেছিলেন, আমি একটি ভাল এবং ক্লিনার সমাধান এখানে পাওয়া করেছি stackoverflow.com/a/21099430/127493 তার কল করে - (void)sizeHeaderToFitviewDidLayoutSubviews
মার্টিন

4

কোড:

  extension UITableView {

          func sizeHeaderToFit(preferredWidth: CGFloat) {
            guard let headerView = self.tableHeaderView else {
              return
            }

            headerView.translatesAutoresizingMaskIntoConstraints = false
            let layout = NSLayoutConstraint(
              item: headerView,
              attribute: .Width,
              relatedBy: .Equal,
              toItem: nil,
              attribute:
              .NotAnAttribute,
              multiplier: 1,
              constant: preferredWidth)

            headerView.addConstraint(layout)

            let height = headerView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
            headerView.frame = CGRectMake(0, 0, preferredWidth, height)

            headerView.removeConstraint(layout)
            headerView.translatesAutoresizingMaskIntoConstraints = true

            self.tableHeaderView = headerView
          }
  }

এটি কাজ করে all সমস্ত টেবিলহেডভিউ সাবভিউতে যথাযথ অটোলেআউট সীমাবদ্ধতা দিন। আপনি যদি একটি একক প্রতিবন্ধকতা মিস করেন তবে এটি কার্যকর হবে না।
অভিমুরলিধরণ

4

টেবিল পাদলেখ দেখার জন্য এই সমাধানটি http://collindonnell.com/2015/09/29/dynamically-sized-table-view-header-or-footer- using-auto-layout/ এর জন্য প্রসারিত :

@interface AutolayoutTableView : UITableView

@end

@implementation AutolayoutTableView

- (void)layoutSubviews {
    [super layoutSubviews];

    // Dynamic sizing for the header view
    if (self.tableHeaderView) {
        CGFloat height = [self.tableHeaderView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
        CGRect headerFrame = self.tableHeaderView.frame;

        // If we don't have this check, viewDidLayoutSubviews() will get
        // repeatedly, causing the app to hang.
        if (height != headerFrame.size.height) {
            headerFrame.size.height = height;
            self.tableHeaderView.frame = headerFrame;
            self.tableHeaderView = self.tableHeaderView;
        }

        [self.tableHeaderView layoutIfNeeded];
    }

    // Dynamic sizing for the footer view
    if (self.tableFooterView) {
        CGFloat height = [self.tableFooterView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
        CGRect footerFrame = self.tableFooterView.frame;

        // If we don't have this check, viewDidLayoutSubviews() will get
        // repeatedly, causing the app to hang.
        if (height != footerFrame.size.height) {
            footerFrame.size.height = height;
            self.tableFooterView.frame = footerFrame;
            self.tableFooterView = self.tableFooterView;
        }

        self.tableFooterView.transform = CGAffineTransformMakeTranslation(0, self.contentSize.height - footerFrame.size.height);
        [self.tableFooterView layoutIfNeeded];
    }
}

@end

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

ওহে! আপনি দয়া করে কিছু self.tableFooterView.transformঅংশ ব্যাখ্যা করতে পারেন ? কেন এটি প্রয়োজনীয়?
mrvn

@ এমআরভিএন রূপান্তরটি পাদচরণটি টেবিলভিউয়ের নীচে সরাতে ব্যবহৃত হয়।
k06a

3

আপনি সিস্টেমলাউটসাইজ ফিটিংসাইজ পদ্ধতিটি ব্যবহার করে আপনাকে একটি আকার সরবরাহ করতে অটোলেআউট পেতে পারেন ।

তারপরে আপনি এটি আপনার অ্যাপ্লিকেশনের জন্য ফ্রেম তৈরি করতে ব্যবহার করতে পারেন। এই কৌশলটি যখনই আপনাকে অভ্যন্তরীণভাবে অটোলেআউট ব্যবহার করে এমন দৃশ্যের আকার জানতে হবে works

সুইফটে কোডটি দেখতে মনে হচ্ছে

//Create the view
let tableHeaderView = CustomTableHeaderView()

//Set the content
tableHeaderView.textLabel.text = @"Hello world"

//Ask auto layout for the smallest size that fits my constraints    
let size = tableHeaderView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

//Create a frame    
tableHeaderView.frame = CGRect(origin: CGPoint.zeroPoint, size: size)

//Set the view as the header    
self.tableView.tableHeaderView = self.tableHeaderView

অথবা অবজেক্টিভ-সি তে

//Create the view
CustomTableHeaderView *header = [[CustomTableHeaderView alloc] initWithFrame:CGRectZero];

//Set the content
header.textLabel.text = @"Hello world";

//Ask auto layout for the smallest size that fits my constraints
CGSize size = [header systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];

//Create a frame
header.frame = CGRectMake(0,0,size.width,size.height);

//Set the view as the header  
self.tableView.tableHeaderView = header

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


3

নিম্নলিখিত আমার জন্য কাজ করে।

  1. UIViewশিরোনামের দর্শন হিসাবে প্লেইন পুরানো ব্যবহার করুন ।
  2. এতে সাবভিউ যুক্ত করুন UIView
  3. সাবউভিউগুলিতে অটোলেআউট ব্যবহার করুন

আমি যে প্রধান সুবিধাটি দেখি তা হ'ল ফ্রেম গণনা সীমিত করা। UITableViewএটিকে আরও সহজ করার জন্য অ্যাপলের সত্যিকারের এপিআই আপডেট করা উচিত ।

স্ন্যাপকিট ব্যবহারের উদাহরণ:

let layoutView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.width, height: 60))
layoutView.backgroundColor = tableView.backgroundColor
tableView.tableHeaderView = layoutView

let label = UILabel()
layoutView.addSubview(label)
label.text = "I'm the view you really care about"
label.snp_makeConstraints { make in
    make.edges.equalTo(EdgeInsets(top: 10, left: 15, bottom: -5, right: -15))
}

3

অদ্ভুত জিনিস ঘটে। systemLayoutSizeFittingSize iOS9 এর জন্য দুর্দান্ত কাজ করে তবে আমার ক্ষেত্রে আইওএস 8 এর জন্য নয় doesn't সুতরাং এই সমস্যাগুলি বেশ সহজ সমাধান করে। সিজিআরেক্টগেটম্যাক্সাইওয়াই (আপনার ভিউ.ফ্রেম) + প্যাডিং হিসাবে উচ্চতা সন্নিবেশ করে সুপার কল আপডেট হেডার ভিউ সীমানার পরে কেবল শিরোনাম এবং ভিউডিডিউলআউটসুভিউগুলিতে নীচের দৃশ্যে লিঙ্ক পান get

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

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    CGFloat height = CGRectGetMaxY(self.tableView.tableHeaderView.subviews.firstObject.frame);
    self.tableView.tableHeaderView.bounds = CGRectMake(0, 0, CGRectGetWidth(self.tableView.bounds), height);
    self.tableView.tableHeaderView = self.tableView.tableHeaderView;
}

ফলস্বরূপ সাবভিউটি প্রসারিত / সঙ্কুচিত হওয়া উচিত যেমনটি করা উচিত, শেষে এটি ভিউডিডলয়আউটসুভিউগুলি বলে। সেই সময়ে আমরা দেখার আসল আকারটি জানি, সুতরাং শিরোনাম দেখার উচ্চতা নির্ধারণ করুন এবং পুনরায় বরাদ্দকরণের মাধ্যমে এটি আপডেট করুন। একটি যাদুমন্ত্র মত কাজ করে!

পাদলেখ দেখার জন্যও কাজ করে।


4
এটি আইওএস ১০ এ লুপ করে
সাইমন

3

সুইফট ৪.২ এর জন্য আপডেট হয়েছে

extension UITableView {

    var autolayoutTableViewHeader: UIView? {
        set {
            self.tableHeaderView = newValue
            guard let header = newValue else { return }
            header.setNeedsLayout()
            header.layoutIfNeeded()
            header.frame.size = 
            header.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
            self.tableHeaderView = header
        }
        get {
            return self.tableHeaderView
        }
    }
}

2

সঠিকভাবে স্থাপন করতে, আপনি শিরোনাম এবং টেবিলভিউয়ের মধ্যে শীর্ষ + অনুভূমিক অবস্থানের সীমাবদ্ধতা যুক্ত করতে পারেন, সঠিকভাবে (যদি শিরোনামে নিজেই সঠিক ফ্রেমের জন্য সমস্ত প্রয়োজনীয় অভ্যন্তরীণ বিন্যাসের সীমাবদ্ধতা থাকে)

সারণীতেভিউ নিয়ন্ত্রণকারী দেখুনডিডলড পদ্ধতিতে

    headerView.translatesAutoresizingMaskIntoConstraints = false

    tableView.tableHeaderView = headerView

    headerView.widthAnchor.constraint(equalTo: tableView.widthAnchor).isActive = true
    headerView.topAnchor.constraint(equalTo: tableView.topAnchor).isActive = true
    headerView.centerXAnchor.constraint(equalTo: tableView.centerXAnchor).isActive = true

1

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

তারপরে আপনার টেক্সট শিরোনামের layoutSubviewsপদ্ধতির মধ্যে ইনিশিয়ালাইজারের পরিবর্তে বাজেটের সীমাবদ্ধতা যুক্ত করুন । যে ক্র্যাশ সমাধান।

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:CGRectMake(0, 0, 0, 44.0)];
    if (self) {
        UIView *contentView = [[UIView alloc] initWithFrame:self.bounds];
        contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth;

        // add other objects as subviews of content view

    }
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];

    // remake constraints here
}

1

আমার অটোলআউট খুব ভাল কাজ করছে:

CGSize headerSize = [headerView systemLayoutSizeFittingSize:CGSizeMake(CGRectGetWidth([UIScreen mainScreen].bounds), 0) withHorizontalFittingPriority:UILayoutPriorityRequired verticalFittingPriority:UILayoutPriorityFittingSizeLevel];
headerView.frame = CGRectMake(0, 0, headerSize.width, headerSize.height);
self.tableView.tableHeaderView = headerView;

আমি ঠিক এটি করিনি তবে আপনি আমাকে একটি ভাল ধারণা দিয়েছেন - শিরোলেখের দৃশ্যটি সরিয়ে, এর ফ্রেমটি পুনরায় সেট করে, এবং এটিকে আবার যুক্ত করে।
দিনেশজানি

1

বেশিরভাগ ক্ষেত্রে সর্বোত্তম সমাধান হ'ল ফ্রেমওয়ার্কের সাথে লড়াই করা এবং অটোরসাইজিং মাস্কগুলি আলিঙ্গন করা নয়:

// embrace autoresizing masks and let the framework add the constraints for you
headerView.translatesAutoresizingMaskIntoConstraints = true
headerView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

// figure out what's the best size based on the table view width
let width = self.tableView.frame.width
let targetSize = headerView.systemLayoutSizeFitting(CGSize(width: width, height: CGFloat.greatestFiniteMagnitude), withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel)
headerView.frame.size = targetSize
self.tableView.tableHeaderView = headerView

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


0

আমি জানি এটি একটি পুরানো পোস্ট তবে এটি সম্পর্কিত সমস্ত এসও পোস্টগুলিতে যাওয়ার পরে এবং পুরো দুপুরটি এই সাথে খেলে আমি অবশেষে একটি পরিষ্কার এবং এখনও খুব সাধারণ সমাধান নিয়ে এসেছি

প্রথমত, আমার দর্শন শ্রেণিবিন্যাসটি দেখতে এমন দেখাচ্ছে:

  1. টেবিল দেখুন
    1. দেখুন tableHeaderView
      1. হেডারভিউ নামে একটি আউটলেট দিয়ে দেখুন

এখন ভিউ (নং 3) এর ভিতরে আমি সমস্ত বাধা সেট আপ করেছি কারণ আমি সাধারণত নীচের স্থানটি ধারক পর্যন্ত অন্তর্ভুক্ত করে থাকি। এটি কনটেইনারটিকে (যেমন 3.ভিউ অর্থাত্‍ শিরোনামের দৃশ্যটি) নিজের সাবউভিউ এবং তাদের সীমাবদ্ধতার ভিত্তিতে আকার দেবে।

এর পরে, আমি 3. Viewএবং 2. Viewএইগুলির মধ্যে সীমাবদ্ধতাগুলি সেট করেছি :

  1. ধারক থেকে শীর্ষ স্থান: 0
  2. ধারক থেকে শীর্ষস্থান: 0
  3. ধারক স্থান অবধি: 0

লক্ষ্য করুন যে আমি ইচ্ছাকৃতভাবে নীচের জায়গাটি বাদ দিয়েছি।

স্টোরিবোর্ডে এই সবগুলি হয়ে গেলে, যা করা বাকি আছে তা হ'ল এই তিনটি লাইনের কোডগুলি পেস্ট করুন:

if (self.headerView.frame.size.height != self.tableView.tableHeaderView.frame.size.height) {
    UIView *header = self.tableView.tableHeaderView;
    CGRect frame = self.tableView.tableHeaderView.frame;
    frame.size.height = self.headerView.frame.size.height + frame.origin.y;
    header.frame = frame;
    self.tableView.tableHeaderView = header;
}

0

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

কোড শো


0

আমার পদ্ধতি শেয়ার করুন।

UITableView+XXXAdditions.m

- (void)xxx_setTableHeaderView:(UIView *)tableHeaderView layoutBlock:(void(^)(__kindof UIView *tableHeaderView, CGFloat *containerViewHeight))layoutBlock {
      CGFloat containerViewHeight = 0;
      UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectZero];
      [backgroundView addSubview:tableHeaderView];
      layoutBlock(tableHeaderView, &containerViewHeight);

      backgroundView.frame = CGRectMake(0, 0, 0, containerViewHeight);

      self.tableHeaderView = backgroundView;
}

ব্যবহার

[self.tableView xxx_setTableHeaderView:myView layoutBlock:^(__kindof UIView * _Nonnull tableHeaderView, CGFloat *containerViewHeight) {
    *containerViewHeight = 170;

    [tableHeaderView mas_makeConstraints:^(MASConstraintMaker *make) {
      make.top.equalTo(@20);
      make.centerX.equalTo(@0);
      make.size.mas_equalTo(CGSizeMake(130, 130));
    }];
  }];

0

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

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    [self resizeHeaderToFitSubview];
}

- (void)resizeHeaderToFitSubview
{
    UIView *header = self.tableView.tableHeaderView;
    [header setNeedsLayout];
    [header layoutIfNeeded];
    CGFloat height = CGRectGetHeight(header.subviews.firstObject.bounds);
    header.bounds = CGRectMake(0, 0, CGRectGetWidth(self.tableView.bounds), height);
    self.tableView.tableHeaderView = nil;
    self.tableView.tableHeaderView = header;
}

0

একটি পুরানো পোস্ট। তবে একটি ভাল পোস্ট। এখানে আমার 2 সেন্ট।

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

//ViewDidLoad
headerView.translatesAutoresizingMaskIntoConstraints = false
headerView.configure(title: "Some Text A")

//Somewhere else
headerView.update(title: "Some Text B)

private var widthConstrained = false

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if widthConstrained == false {
        widthConstrained = true
        tableView.addConstraint(NSLayoutConstraint(item: headerView, attribute: .width, relatedBy: .equal, toItem: tableView, attribute: .width, multiplier: 1, constant: 0))
        headerView.layoutIfNeeded()
        tableView.layoutIfNeeded()
    }
}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    coordinator.animate(alongsideTransition: { (context) in
        self.headerView.layoutIfNeeded()
        self.tableView.layoutIfNeeded()
    }, completion: nil)
}

0

আমি নিম্নলিখিত পদ্ধতির মাধ্যমে এটি অর্জন করতে সক্ষম হয়েছি (এটি পাদলেখার জন্য একইভাবে কাজ করে)।

প্রথমত, আপনার ছোট UITableViewবর্ধনের প্রয়োজন হবে :

সুইফট 3

extension UITableView {
    fileprivate func adjustHeaderHeight() {
        if let header = self.tableHeaderView {
            adjustFrame(header)
        }
    }

    private func adjustFrame(_ view: UIView) {
        view.frame.size.height = calculatedViewHeight(view)
    }

    fileprivate func calculatedHeightForHeader() -> CGFloat {
        if let header = self.tableHeaderView {
            return calculatedViewHeight(header)
        }
        return 0.0
    }

    private func calculatedViewHeight(_ view: UIView) -> CGFloat {
        view.setNeedsLayout()
        let height = view.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
        return height
    }
}

আপনার দৃষ্টিতে নিয়ামক শ্রেণীর প্রয়োগ:

// this is a UIView subclass with autolayout
private var headerView = MyHeaderView()

override func loadView() {
    super.loadView()
    // ...
    self.tableView.tableHeaderView = headerView
    self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension
    // ...
}

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    // this is to prevent recursive layout calls
    let requiredHeaderHeight = self.tableView.calculatedHeightForHeader()
    if self.headerView.frame.height != requiredHeaderHeight {
        self.tableView.adjustHeaderHeight()
    }
}

শিরোনামের UIViewসাবভিউ বাস্তবায়ন সম্পর্কে নোটগুলি :

  1. আপনার 100% নিশ্চিত থাকতে হবে যে আপনার শিরোনাম দর্শনটিতে সঠিক অটোলেআউট সেটআপ রয়েছে। আমি কেবলমাত্র এক উচ্চতার প্রতিবন্ধকতা সহ সাধারণ হেডার ভিউ দিয়ে শুরু করার এবং উপরের সেটআপটি ব্যবহার করার পরামর্শ দেব।

  2. ওভাররাইড requiresConstraintBasedLayoutএবং ফিরে true:

class MyHeaderView: UIView {
   // ...
   override static var requiresConstraintBasedLayout : Bool {
       return true
   }
   // ...
}

0

জামারিন ব্যবহারকারীদের জন্য:

public override void ViewDidLayoutSubviews()
{
    base.ViewDidLayoutSubviews();

    TableviewHeader.SetNeedsLayout();
    TableviewHeader.LayoutIfNeeded();

    var height = TableviewHeader.SystemLayoutSizeFittingSize(UIView.UILayoutFittingCompressedSize).Height;
    var frame = TableviewHeader.Frame;
    frame.Height = height;
    TableviewHeader.Frame = frame;
}

ধরে নিচ্ছি যে আপনি আপনার টেবিলভিউয়ের শিরোনাম দৃশ্যের নাম টেবিলভিউহাইডার হিসাবে রেখেছেন


0

আপনি কীভাবে এটি করতে পারেন তা এখানে UIViewController

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if headerView.frame.size.height == 0 {
      headerView.label.preferredMaxLayoutWidth = view.bounds.size.width - 20
      let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height

      headerView.frame.size = CGSize(width: tableView.bounds.size.width, height: height)
    }
  }

0

যে কোনও সীমাবদ্ধ-ভিত্তিক UIViewভাল হতে পারে tableHeaderView

এক চাহিদা একটি সেট করতে tableFooterViewসামনে এবং তারপর অতিরিক্ত চিহ্ন বাধ্যতা আরোপ tableFooterViewএবং tableHeaderView

- (void)viewDidLoad {

    ........................
    // let self.headerView is some constraint-based UIView
    self.tableView.tableFooterView = [UIView new];
    [self.headerView layoutIfNeeded];
    self.tableView.tableHeaderView = self.headerView;

    [self.tableView.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor].active = YES;
    [self.tableView.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor].active = YES;
    [self.tableView.topAnchor constraintEqualToAnchor:self.headerView.topAnchor].active = YES;
    [self.tableFooterView.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor].active = YES;

}

একজন এখানে সমস্ত বিবরণ এবং কোড স্নিপেটগুলি পেতে পারেন


0

আমি একটি কাজ খুঁজে বের করেছি। একটি খালি ইউভিউ র‍্যাপারে আপনার অটোলেআউট ক্রিটিন এক্সিব শিরোলেখের দৃশ্যটি মোড়ানো করুন এবং টেবিলভিউয়ের টেবিলভিউহাইডারের সম্পত্তিতে শিরোলেখ প্রদর্শনটি নির্ধারণ করুন।

    UIView *headerWrapper = [[UIView alloc] init];
    AXLHomeDriverHeaderView *headerView = [AXLHomeDriverHeaderView loadViewFromNib];
    [headerWrapper addSubview:headerView];
    [headerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(headerWrapper);
    }];
    self.tableView.tableHeaderView = headerView;

0

আইওএস 12-এ ইউআইটিএবল ভিউ কনট্রোলারের জন্য কী কাজ করে তা এখানে,

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

এখন নিম্নলিখিত এক্সটেনশন পদ্ধতি ব্যবহার করুন

public static class UITableVIewExtensions
{

    public static void MakeHeaderAutoDimension(this UITableView tableView)
    {
        if (tableView.TableHeaderView is UIView headerView) {
            var size = headerView.SystemLayoutSizeFittingSize(UIView.UILayoutFittingCompressedSize);
            if (headerView.Frame.Size.Height != size.Height) {
                var frame = headerView.Frame;
                frame.Height = size.Height;
                headerView.Frame = frame;
                tableView.TableHeaderView = headerView;
                tableView.LayoutIfNeeded();
            }
        }
    }

    public static void MakeFooterAutoDimension(this UITableView tableView)
    {
        if (tableView.TableFooterView is UIView footerView) {
            var size = footerView.SystemLayoutSizeFittingSize(UIView.UILayoutFittingCompressedSize);
            if (footerView.Frame.Size.Height != size.Height) {
                var frame = footerView.Frame;
                frame.Height = size.Height;
                footerView.Frame = frame;
                tableView.TableFooterView = footerView;
                tableView.LayoutIfNeeded();
            }
        }
    }
}

এবং এটিকে ইউআইটিএবল ভিউকন্ট্রোলারের সাবক্লাসের ভিউডিডলয়আউটসুভিউগুলিতে কল করুন

public override void ViewDidLayoutSubviews()
{
    base.ViewDidLayoutSubviews();

    TableView.MakeHeaderAutoDimension();
    TableView.MakeFooterAutoDimension();
}

0

আমি 375pt প্রস্থের সমস্যার মুখোমুখি হয়েছি, আমার পক্ষে কাজ করার একমাত্র উপায় হ'ল সঠিক প্রস্থটি পেতে টেবিলভিউটি পুনরায় আউট করা। আমি ফ্রেমের আকার নির্ধারণের চেয়ে অটলআউটকেও প্রাধান্য দিয়েছি।

আমার জন্য কাজ করা সংস্করণটি এখানে:

Xamarin.iOS

public static void AutoLayoutTableHeaderView(this UITableView tableView, UIView header)
{
    tableView.TableHeaderView = header;
    tableView.SetNeedsLayout();
    tableView.LayoutIfNeeded();
    header.WidthAnchor.ConstraintEqualTo(tableView.Bounds.Width).Active = true;       
    tableView.TableHeaderView = header;
}

সুইফ্ট সংস্করণ (@ বেন প্যাকার্ড উত্তর থেকে সংশোধিত)

extension UITableView {
    //set the tableHeaderView so that the required height can be determined, update the header's frame and set it again
    func setAndLayoutTableHeaderView(header: UIView) {
        self.tableHeaderView = header
        self.setNeedsLayout()
        self.layoutIfNeeded()
        header.widthAnchor.widthAnchor.constraint(equalTo: self.bounds.width).isActive = true
        self.tableHeaderView = header
    }
}


0

আমার সমাধানটি এইভাবে একটি নতুন শ্রেণি তৈরি করছে।

class BaseTableHeaderView: UIView {

    func sizeToFitBasedOnConstraints(width: CGFloat = Screen.width) {
        let size = systemLayoutSizeFitting(CGSize(width: width, height: 10000),
                                              withHorizontalFittingPriority: .required,
                                              verticalFittingPriority: .fittingSizeLevel)
        frame = CGRect(origin: .zero, size: size)
    }

    override func willMove(toSuperview newSuperview: UIView?) {
        sizeToFitBasedOnConstraints()
        super.willMove(toSuperview: newSuperview)
    }

}

এটি ব্যবহার করতে, কেবলমাত্র আপনার সমস্ত সাবভিউ একটি দৃষ্টান্তের সাথে জুড়ুন BaseTableHeaderViewএবং এটি আপনার টেবিল দৃশ্যে সংযুক্ত করুন।

let tableHeaderView = BaseTableHeaderView()
tableHeaderView.addSubview(...)
tableView.tableHeaderView = tableHeaderView

এটি তার সীমাবদ্ধতার উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে আকার পরিবর্তন করবে।


-1

স্বীকৃত উত্তর কেবলমাত্র একটি বিভাগের টেবিলগুলির জন্য দরকারী। বহু বিভাগের জন্য UITableViewকেবল আপনার হেডার উত্তরাধিকার সূত্রে নিশ্চিত হয়ে নিনUITableViewHeaderFooterView এবং আপনি ভাল থাকবেন।

বিকল্প হিসাবে, কেবলমাত্র আপনার বর্তমান শিরোনামটিকে contentViewএকটি এর মধ্যে এম্বেড করুন UITableViewHeaderFooterView। হুবহু UITableViewCellকাজের মতো ।


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