2011-01-09 3 views
46

У меня есть трудности при добавлении подвид (UIView) внутри метода viewDidLoad в виде UITableViewControllerКак добавить UIView выше текущей UITableViewController

Это работает:

[self.view addSubview:self.progView]; 

Но вы можете увидеть ячейку таблицы линии просачиваются через Uview progView.

Я попробовал этот подход:

[self.view.superview insertSubview:self.progView aboveSubview:self.view]; 

который является попыткой добавить progView, UIView к надтаблицы, выше текущего вида. Когда я пытаюсь это сделать, UIView никогда не появляется.

- ОБНОВЛЕНИЕ -

Ниже последняя попытка:

UIView *myProgView = (UIView *)self.progView; //progView is a method that returns a UIView 

[self.tableView insertSubview:myProgView aboveSubview:self.tableView]; 
[self.tableView bringSubviewToFront:myProgView]; 

Результат такой же, как [self.view addSubview: self.progView]; UIView появляется, но, по-видимому, за столом.

+2

Вы пытались использовать 'aboveSubview: self.view'? Я не говорю, что это решит вашу проблему, но похоже, что она избавится от сообщения об ошибке, которое вы получаете. –

+0

Да, я попробовал это. Верно, что я потерял предупреждение, но он все равно не отображает представление. Я отредактирую свой пост, хотя. – user558096

+0

Простой метод задает рамки progVIew, и я уверен, что он может работать. Любое ограничение не будет работать, в том числе VFL – BollMose

ответ

1

попробовать: [self.view bringSubviewToFront:self.progView];

Или вы можете попробовать добавить self.progView для просмотра вашего стола.

+0

[self.view bringSubViewToFront: self.progView]; дает мне предупреждение: «UIView» может не отвечать на «-bringSubViewToFront:» и выдает сообщение об ошибке «исключение неизвестного пользователя, отправленного на экземпляр». – user558096

+0

, так что ваш контроллер - это UITableViewController? – WrightsCS

+0

Да, мой контроллер - это UITableViewController. – user558096

6

Проблема в том, что свойство viewUITableViewController идентично tableView. Это означает, что в корневом представлении всегда есть контроллер табличного представления, и все, что добавлено в качестве подзапроса, будет подчиняться функциональности представления таблиц. У этого есть другие нежелательные побочные эффекты, такие как прокрутки вашего подпрограммы, когда вы не можете их хотеть.

Здесь пара вариантов. Вы можете переопределить loadView и установить свой собственный вид и вид таблицы:

// note: untested 
- (void)loadView { 
    self.view = [[[UIView alloc] initWithFrame:CGRectZero] autorelease]; 
    self.view.backgroundColor = [UIColor whiteColor]; 

    UITableView *tblView = [[UITableView alloc] 
     initWithFrame:CGRectZero 
     style:UITableViewStylePlain 
    ]; 

    tblView.autoresizingMask = 
     UIViewAutoresizingFlexibleWidth | 
     UIViewAutoresizingFlexibleHeight 
    ; 

    self.tableView = tblView; 
    [self.view addSubview:tblView]; 
    [tblView release]; 
} 

И тогда, когда вам нужно добавить подвид, добавьте его ниже или выше self.tableView по мере необходимости.

Другой вариант - это создать подкласс UIViewController, который сделает все, что вам нужно. UITableViewController честно не добавляет этого, и небольшая функциональность, которую он реализует, легко реплицируется. Есть статьи вроде Recreating UITableViewController to increase code reuse, которые объясняют, как это сделать довольно легко.

+0

Спасибо за помощь здесь. К сожалению, я действительно стараюсь сделать ваше первое предложение. Возможно, то, что я пытаюсь сделать, невозможно. На данный момент я пытаюсь сделать UIView сам.представление подкласса UITableViewController. А затем сделайте UITableView подвью UIView. Не похоже, что это можно было бы сделать, и мне действительно нужно преобразовать мой UITableViewController в UIViewController в соответствии с вашими вторыми предложениями. Любые идеи или указатели на учебные пособия или примеры кода, которые могут быть полезны. Заранее спасибо. – user558096

+1

Я бы не ссылался на self.view, чтобы читать из loadView, вы попадете в бесконечный цикл. Только назначьте его. – Diziet

5

Пример Apple «iPhoneCoreDataRecipes» использует NIB для загрузки заголовка в UITableView. См. here:

+0

Я согласен с этим ответом! – Jagie

11

Ive смог добавить подвью на вершине uitableviewcontroller с помощью утилиты uiviewcontroller.

UITableViewController на самом деле очень удобен, когда дело доходит до статических ячеек, и это, вероятно, единственный раз, когда общий ответ «просто использовать uitableview» может быть фактически нежизнеспособным.

Так вот как я это делаю.

  1. дать ваш UITableViewController раскадровка идентификатор, т.е.MyStaticTableView
  2. создать совершенно новый UIViewController подкласса и называют его UITableViewControllerContainer
  3. место этот контроллер в месте вашего UITableViewController в раскадровку
  4. добавить подвид на новый контроллер и связать его с выход под названием «view_container»
  5. на вас UITableViewControllerContainer viewDidLoad метод

добавить код вроде:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 
    UITableViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"MyStaticTableView"]; 
    [self addChildViewController:vc]; 
    [self.view_container addSubview:vc.view]; 
} 

Проблемы вы можете иметь:

  1. , если у вас есть дополнительное верхнее пространство, то не забудьте добавить флаг «хочет Fullscreen» к вашему UITableViewController
  2. , если он не изменяет размер на вашем UITableViewControllerContainer

добавить код:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [[self.view_container.subviews lastObject] setFrame:self.view.frame]; 
} 

в этот момент из вашего UITableViewController вы можете получить доступ к вам вид контейнера непосредственно с

self.view.superview.superview

и все, что вы добавляете к нему будет отображаться сверху ваш контроллер табличного вида

+1

От iOS 6.0 и выше UIContainerView делает решение еще проще. – eladleb

87

Я попробовал a pproach выше, но не получил его на работу. Я также счел, что для этого требуется слишком много настроек и кода, поскольку для этого требуется создание табличного представления с нуля (что легко сделать изнутри раскадровки).

Вместо этого я добавил мнение, что я хотел добавить выше моего UITableView в поле зрения UITableViewController в UINavigationController, поскольку такие:

[self.navigationController.view addSubview:<view to add above the table view>]; 

Этот подход требует, чтобы вы встроили в UITableViewController в UINavigationController, но даже если вам не нужен контроллер навигации, вы все равно можете использовать этот подход и просто скрыть панель навигации.

+9

Проблема с вашим решением заключается в том, что когда вы это делаете, представление также добавляется через панель навигации. – Mittchel

+34

Вы можете сделать это: '[self.navigationController.view insertSubview: holderView belowSubview: self.navigationController.navigationBar];' –

+1

Другой проблема в том, что добавленный вид остается поверх UINavigationController, даже после нажатия нового UIViewController. – Raphael

28

Это на самом деле вполне возможно и просто - для этого требуется просто переделка. Я столкнулся с подобной ситуацией и закодировал это, чтобы позволить мне добавлять экраны загрузки поверх моих табличных представлений. Этот подход также позволяет использовать статические ячейки таблицы с вашим собственным контентом.

Если ваш контроллер является UITableViewController в раскадровке или XIB, и вы хотите переназначить себя.вид на стандартный UIView, сохраняя существующий вид таблицы:

Добавьте эти переменные экземпляра в файл заголовка:

IBOutlet UITableView *tableViewReference; // to keep a reference to the tableview 
UIView *viewReference; // a reference to the new background view 

В вашем раскадровки или XIB файла: Подключите tableView в UITableViewController к переменная tableViewReference.

Затем в файле реализации:

// Override the default accessors of the tableview and view 
- (UITableView*)tableView { return tableViewReference; } 
- (UIView*)view { return viewReference; } 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // instantiate the new self.view, similar to the tableview 
    viewReference = [[UIView alloc] initWithFrame:tableViewReference.frame]; 
    [viewReference setBackgroundColor:tableViewReference.backgroundColor]; 
    viewReference.autoresizingMask = tableViewReference.autoresizingMask; 
    // add it as a subview 
    [viewReference addSubview:tableViewReference]; 

    /* remainder of viewDidLoad */ 

} 

Хотя это может показаться странным, UITableViewController делает много изворотливого материала со ссылками за кулисами. Вам нужно дождаться viewDidLoad, чтобы сделать своп. После этого точки доступа будут указывать на правильные UIView и UITableView.

Использование: Что-то вроде

[self.view addSubview:myView]; 

добавит UIView myView перед табличным, без myView прокрутки с содержанием табличного представления.

Примечание: Этот ответ редактировался после того, как было указано, что решение содержит пограничный парадоксальный код. UITableViewController делает странные вещи для ссылок, которые он имеет. Более тщательное тестирование получило этот более простой ответ :)

+0

Я не понимаю, как это может работать, когда вы делаете '- (UITableView *) tableView { return mainTableView; } 'и вызывать после' mainTableView = self.tableView; 'это как делать' mainTableView = mainTableView' ... – AncAinu

+0

@AncAinu Если вы прочтете примечание, которое я вставил чуть ниже кода, вы увидите, что он должен остановиться теряя ссылку на него. Не понимаю, почему это заслужило ниспровержение. –

+0

@ThomasVerbeek, потому что то, что вы делаете, совершенно непригодно. '- (UITableView *) tableView' заменяет исходный' self.tableView', поэтому, когда вы вызываете 'mainTableView = self.tableView;' это как вызов 'mainTableView = mainTableView' и потому, что вы никогда не назначали его раньше, это похоже на выполнение' nil = nil'. Ваш 'mainTableView' никогда не заполняется чем-то в этом коде. – AncAinu

4

Я добавил изображение над таблицей. Я использовал этот код:

self.tableView.tableHeaderView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"header.png"]]; 
0

у меня была аналогичная проблема, где я хотел, чтобы добавить индикатор загрузки в верхней части моей UITableViewController. Чтобы решить эту проблему, я добавил UIView в качестве подвид окна. Это решило проблему. Вот как я это сделал.

-(void)viewDidLoad{ 
    [super viewDidLoad]; 
    //get the app delegate 
    XYAppDelegate *delegate = [[UIApplication sharedApplication] delegate]; 

    //define the position of the rect based on the screen bounds 
    CGRect loadingViewRect = CGRectMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2, 50, 50); 
    //create the custom view. The custom view is a property of the VIewController 
    self.loadingView = [[XYLoadingView alloc] initWithFrame:loadingViewRect]; 
    //use the delegate's window object to add the custom view on top of the view controller 
    [delegate.window addSubview: loadingView]; 
} 
0

Могут быть причины не делать этого, но это работает для меня до сих пор. Если вы используете ТЧД

Внутри viewDidLayoutSubviews вы можете запустить, но убедитесь, что только один раз запустить его, очевидно

self.searchTableView = [[UITableView alloc] initWithFrame:self.tableView.frame style:UITableViewStylePlain]; 
self.searchTableView.backgroundColor = [UIColor purpleColor]; 
[self.view.superview addSubview:self.searchTableView]; 
8

Вы можете увеличить zPosition слоя вашего зрения.

Это позволит отобразить над другими видами (которые имеют zPosition, равное 0, по умолчанию)

self.progView.layer.zPosition++; 
[self.view addSubview:self.progView]; 
+0

Это сработало для меня. Я просто использую обычный UIViewController с UITableView, и я хотел бы разместить нижний колонтитул, который сидел над табличным представлением. По какой-то причине, если я привел зрителя для ног на фронт через вызов 'bringSubviewToFront' или через Storyboard, UITableView будет нажат вниз. Это оставило большой пробел на самом верху. Я не уверен, почему UITableView не может иметь ничего в иерархии представлений. Изменение свойства 'zPosition' слоя слоя нижнего колонтитула успешно принесло его сверху, не изменяя расположение UITableView. – Sid

+0

Это работает, но слои не обрабатывают взаимодействие с пользователем (вот почему мы имеем UIView). Просто указывая на это. – Chris

0

попробовать что-то вроде этого:

[self.tableView addSubview:overlayView]; 
overlayView.layer.zPosition = self.tableView.backgroundView.layer.zPosition + 1; 
2

У меня была аналогичная проблема, и получил он разрешен с использованием приведенного ниже кода:

 [self.navigationController.view insertSubview:<subview> 
     belowSubview:self.navigationController.navigationBar]; 

Этот вид вставок в правильном месте с использованием контроллеров, присутствующих в стеке ,

2

Поскольку UITableViewController является подклассом UIViewController, вам необходимо добавить нужный вид в его супервизор.

Swift: 
self.view.superview?.addSubview(viewTobeAdded) 

Objective C: 
[self.view.superview addSubview: viewTobeAdded]; 
+0

self.view.superview - это nil для моего UITableViewController (в viewDidLoad) – Jovan

0

Вы можете просто поместить следующий код в viewDidAppear:

[self.tableView.superview addSubview:<your header view>]; 
1

решения для быстрого (эквивалента Daniel Саиди):

Если ваш контроллер является UITableViewController в раскадровке или XIB и вы хотите переназначить self.view на стандартный UIView при сохранении существующего вида таблицы:

@IBOutlet var tableViewReference: UITableView! 
var viewReference: UIView! 

Затем в файле реализация:

Добавьте эти переменный экземпляр в табличном файл контроллер представления:

override var tableView: UITableView! { 
    get { return tableViewReference } 
    set { super.tableView = newValue } 
} 

override var view: UIView! { 
    get { return viewReference } 
    set { super.view = newValue } 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.edgesForExtendedLayout = UIRectEdge.None 
    self.extendedLayoutIncludesOpaqueBars = false 
    self.automaticallyAdjustsScrollViewInsets = false 

    //rewiring views due to add tableView as subview to superview 
    viewReference = UIView.init(frame: tableViewReference.frame) 
    viewReference.backgroundColor = tableViewReference.backgroundColor 
    viewReference.autoresizingMask = tableViewReference.autoresizingMask 
    viewReference.addSubview(tableViewReference) 
} 

В раскадровке или XIB файл: Подключите Tableview в UITableViewController переменной tableViewReference.

Тогда вы будете иметь возможность добавлять дочерние представления следующим образом:

self.view.addSubView(someView) 
1

Чтобы сохранить UIView выше табличном в UITableViewController Я использую один (или более) методов делегата (UITableViewDelegate).

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.tableView.addSubview(headerView) 
} 

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { 
    tableView.addSubview(overlayView) // adds view always on top 
} 
// if using footers in table view 
tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) { ... } 

Как вид может иметь только один SuperView, что швы тоже быть хорошим решением, поправьте меня, если я ошибаюсь. Все еще получаю 60 кадров в секунду, так что это нормально для меня.

+0

Как вы планировали 'overlayView' и' headerVew'? – LShi

0

Обновление для прошивки 11:

Теперь можно добавить подвид к UITableView при использовании AutoLayout ограничений в безопасную зону. Эти представления не будут прокручиваться вдоль TableView.

Этот пример ставит вид под Панель навигации в верхней части UITableView в виде UITableViewController

[self.tableView addSubview:self.topBarView]; 
[NSLayoutConstraint activateConstraints:@[ 
    [self.topBarView.topAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.topAnchor], 
    [self.topBarView.leadingAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.leadingAnchor], 
    [self.topBarView.trailingAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.trailingAnchor], 
    [self.topBarView.heightAnchor constraintEqualToConstant:40.0] 
]]; 
+0

Не могли бы вы объяснить, что такое 'viewController' и какова связь между ним и' UITableViewController'? – LShi

+0

Это должен быть 'UITableViewController' или, скорее, его' tableView'. Я скопировал код из моего подкласса UINavigationController, который имеет ссылку на отображаемый ViewController (который в моем случае является UITableViewController). Я применил пример. – cornr

Смежные вопросы