2015-05-12 16 views
7

Korzystając z komend Storyboards i Autolayout, mam kontroler UIViewController z UIScrollView jako widok główny. Mam kilka widoków kontenerów osadzonych w widoku przewijania. Niektóre widoki osadzonych kontenerów zawierają widoki UITableView, z których każdy ma komórki o różnych wysokościach. Potrzebuję wysokości tableView, aby była wystarczająco duża, aby pokazać wszystkie komórki naraz, ponieważ przewijanie zostanie wyłączone w tableView.Dopasowywanie wysokości widoku kontenera do wbudowanego UITableView

W głównym module UIViewController należy zdefiniować wysokość widoku kontenera, aby widok przewijania działał prawidłowo. Jest to problematyczne, ponieważ nie ma sposobu, aby dowiedzieć się, jak duże będzie moje tableView, gdy wszystkie komórki o różnej wysokości zostaną zakończone. Jak dostosować wysokość widoku kontenera w czasie wykonywania, aby pasował do mojego nie przewijanego widoku UITableView?

tej pory robiłem, co następuje:

// in embedded UITableViewController 
// 
- (void)viewDidLoad { 
    // force layout early so I can determine my table's height 
    [self.tableView layoutIfNeeded]; 

    if (self.detailsDelegate) { 
     [self.detailsTableDelegate didDetermineHeightForDetailsTableView:self.tableView]; 
    } 
} 

// in my main UIViewController 
// I have an IBOutlet to a height constraint set up on my container view 
// this initial height constraint is just temporary, and will be overridden 
// once this delegate method is called 
- (void)didDetermineHeightForDetailsTableView:(UITableView *)tableView 
{ 
    self.detailsContainerHeightConstraint.constant = tableView.contentSize.height; 
} 

to działa dobrze i jestem zadowolony z rezultatów. Mam jednak do dodania jeszcze jeden lub dwa widoki kontenerów, które będą miały nie przewijane widoki tableView i nie chciałbym tworzyć nowego protokołu delegatów dla każdego widoku kontenera. Nie sądzę, żebym mógł stworzyć protokół, który mam generyczny.

Wszelkie pomysły?

+0

Mam do czynienia z podobnym problemem. Czy znalazłeś rozwiązanie tego problemu? – ntsh

+0

@ntsh Właśnie dodałem własną odpowiedź. spójrz i zobacz, czy to ci pomoże – djibouti33

+0

Dzięki. Również skończyłem z podobnym rozwiązaniem przy użyciu contentSize tableView. – ntsh

Odpowiedz

1

Oto, co skończyło się robi:

// In my embedded UITableViewController: 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.tableView.rowHeight = UITableViewAutomaticDimension; 
    self.tableView.estimatedRowHeight = 60.0; 

    // via storyboards, this viewController has been embeded in a containerView, which is 
    // in a scrollView, which demands a height constraint. some rows from our static tableView 
    // might not display (for lack of data), so we need to send our table's height. we'll force 
    // layout early so we can get our size, and then pass it up to our delegate so it can set 
    // the containerView's heightConstraint. 
    [self.tableView layoutIfNeeded]; 

    self.sizeForEmbeddingInContainerView = self.tableView.contentSize; 
} 

// in another embedded view controller:  
- (void)viewDidLayoutSubviews 
{ 
    [super viewDidLayoutSubviews]; 

    self.sizeForEmbeddingInContainerView = self.tableView.contentSize; 
} 

// then, in the parent view controller, I do this: 
// 1) ensure each container view in the storyboard has an outlet to a height constraint 
// 2) add this: 
- (void)viewDidLayoutSubviews 
{ 
    [super viewDidLayoutSubviews]; 

    self.placeDetailsContainerHeightConstraint.constant = self.placeDetailsTableViewController.sizeForEmbeddingInContainerView.height; 
    self.secondaryExperiencesContainerHeightConstraint.constant = self.secondaryExperiencesViewController.sizeForEmbeddingInContainerView.height; 
} 

nie robiłem tego jeszcze, ale że to prawdopodobnie najlepiej stworzyć protokół z majątku CGSize sizeForEmbeddingInContainerView że każde dziecko widok kontroler może przyjąć.

+0

Zaimplementowałeś to działa @ djibouti33 –

+0

Sądzę, że w efekcie powstał protokół. – djibouti33

1

Oto, co zadziałało idealnie.

- (void)updateSizeBasedOnChildViews { 

    // Set height of container to match embedded tableview 
    CGRect containerFrame = self.cardTableContainer.frame; 
    containerFrame.size.height = [[[self.cardTableContainer subviews] lastObject]contentSize].height; 
    self.cardTableContainer.frame = containerFrame; 

    // Set content height of scrollview according to container 
    CGRect scrollFrame = self.cardTabScrollView.frame; 
    scrollFrame.size.height = containerFrame.origin.y + containerFrame.size.height; 
      // + height of any other subviews below the container 
    self.cardTabScrollView.contentSize = scrollFrame.size; 
} 
+0

Skąd się wziął ten telefon - jaką metodę? Moim problemem jest to, że próbuję to zrobić zaraz po didMoveToParentViewController i kontroler nie jest jeszcze załadowany, ale nie mogę wymyślić, jak pozwolić kontrolerowi widoku kontenera wiedzieć kiedy dziecko jest ładowane. – SAHM

+0

@SAHM W moim przypadku wywołałem to po ustawieniu danych dla tableViewController (który wywołuje [tableView reloadData]). Jednak minęło ponad 2 lata temu, więc nie pamiętam dokładnie szczegółów. Mój ostatni kod: w viewDidAppear: '' '[self updateChildViewData]' '', a następnie '' '- (void) updateChildViewData {[self updateChildTableVCData]; [self updateSizeBasedOnChildViews]}' '' – ntsh

Powiązane problemy