iphone - ocultar - Personalizar el menú Más en una barra de pestañas
ocultar barra de direcciones firefox (5)
visiblesCells se completa solo después de que se muestre másNavigationController.
Y las celdas se crean en tiempo de ejecución, por lo que incluso si cambia el contenido de las celdas, se reemplazan cuando se muestran.
Una cosa que debe intentarse es reemplazar el origen de datos de moreNavigationController tableView, llamar a cellForRowAtIndexPath de la fuente de datos original y cambiar su contenido antes de devolverlo.
Usando el siguiente código, después de haber mostrado una vez más el Controlador de navegación para inicializarlo, verás que cuando regresas al Control de navegación más, las celdas son rojas, pero regresan inmediatamente al fondo blanco.
UITableView *view = (UITableView *)self.tabBarController.moreNavigationController.topViewController.view;
if ([[view subviews] count]) {
for (UITableViewCell *cell in [view visibleCells]) {
cell.backgroundColor = [UIColor redColor];
}
}
Estoy usando una barra de pestañas (UITabBarController) en mi aplicación y deseo personalizar la apariencia de la tabla que aparece al hacer clic en el botón más. He resuelto cómo cambiar la apariencia de la barra de navegación que está en la pantalla más configurando
self.moreNavigationController.navigationBar.barStyle
en una subclase de UITabBarController y he logrado cambiar el color de fondo de la tabla modificando
self.moreNavigationController.topViewController.view.backgroundColor
, pero no puedo descifrar cómo cambiar el color de la fuente en las celdas que aparecen en la tabla. Esperaba poder usar
self.moreNavigationController.topViewController.view.visibleCells
pero esto siempre parece estar vacío. Intenté hacer esto en viewDidLoad, viewWillAppear y viewDidAppear sin éxito. El objeto self.moreNavigationController.topViewController es del tipo UIMoreListController, que parece no estar documentado y no puedo ver nada obvio en la interfaz que me ayude.
¿Algunas ideas?
Seguí la implementación de Ian para personalizar el menú Más, pero estaba teniendo problemas para retener las personalizaciones después de una advertencia de memoria. didReceiveMemoryWarning parece destruir el UITableView, y cuando se regenera recupera su antigua dataSource. Aquí está mi solución:
Sustituyo viewDidLoad en CustomTabBarController con esto:
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController* moreController = self.moreNavigationController;
if ([moreController.topViewController.view isKindOfClass:[UITableView class]]) {
moreController.delegate = self;
self.moreControllerClass = [moreController.topViewController class];
UITableView* view = (UITableView*) moreController.topViewController.view;
self.newDataSource = [[[MoreDataSource alloc] initWithDataSource:view.dataSource] autorelease];
}
}
Como puede ver, agregué algunas propiedades para almacenar cosas que necesitaba. Esos deben agregarse al encabezado y sintetizarse. También hice CustomTabBarController un UINavigationControllerDelegate en el encabezado. Aquí está la función de delegado que agregué:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([viewController isKindOfClass:self.moreControllerClass]) {
UIView* view = self.moreNavigationController.topViewController.view;
if ([view isKindOfClass:[UITableView class]]) {
UITableView* tview = (UITableView*) view;
tview.dataSource = self.newDataSource;
tview.rowHeight = 81.0;
}
}
}
De esta manera, me aseguro de que siempre se use mi fuente de datos personalizada, porque lo configuré de esa manera justo antes de mostrar el UIMoreListController, cada vez que se muestra.
Siguiendo con la sugerencia de Stephan de reemplazar el dataSource del másNavigationController, aquí hay una vista rápida del código que implementé.
Creé una nueva clase llamada MoreTableViewDataSource que implementa el protocolo UITableViewDataSource. El controlador que más páginas usa para construir la tabla se llama UIMoreListControllerModern, y esto implementa solo las partes requeridas del protocolo UITableViewDataSource. Mi implementación se ve así.
-(MoreTableViewDataSource *) initWithDataSource:(id<UITableViewDataSource>) dataSource
{
self = [super init];
if (self)
{
self.originalDataSource = dataSource;
}
return self;
}
- (void)dealloc
{
self.originalDataSource = nil;
[super dealloc];
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
return [originalDataSource tableView:table numberOfRowsInSection:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [originalDataSource tableView:tableView cellForRowAtIndexPath:indexPath];
cell.textColor = [UIColor whiteColor];
return cell;
}
y luego en mi clase CustomTabBarController anulo viewDidLoad de la siguiente manera:
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController *moreController = self.moreNavigationController;
moreController.navigationBar.barStyle = UIBarStyleBlackOpaque;
if ([moreController.topViewController.view isKindOfClass:[UITableView class]])
{
UITableView *view = (UITableView *)moreController.topViewController.view;
view.backgroundColor = [UIColor blackColor];
moreTableViewDataSource = [[MoreTableViewDataSource alloc] initWithDataSource:view.dataSource];
view.dataSource = moreTableViewDataSource;
}
}
Como se solicita aquí están los archivos de encabezado
@interface MoreTableViewDataSource : NSObject <UITableViewDataSource>
{
id<UITableViewDataSource> originalDataSource;
}
@property (retain) id<UITableViewDataSource> originalDataSource;
-(MoreTableViewDataSource *) initWithDataSource:(id<UITableViewDataSource>) dataSource;
@end
y
#import "MoreTableViewDataSource.h"
@interface CustomTabBarController : UITabBarController
{
MoreTableViewDataSource *moreTableViewDataSource;
}
@interface TabBarViewController () <UITableViewDelegate,UITableViewDataSource>
@property (nonatomic,strong) UITableView* tabBarTableView;
@property (nonatomic,weak) id <UITableViewDelegate> currentTableViewDelegate;
@end
@implementation TabBarViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self costumizeMoreTableView];
}
-(void)costumizeMoreTableView{
_tabBarTableView = (UITableView *)self.moreNavigationController.topViewController.view;
_currentTableViewDelegate = _tabBarTableView.delegate;
_tabBarTableView.delegate = self;
_tabBarTableView.dataSource = self;
[_tabBarTableView registerNib:[UINib nibWithNibName:@"MoreTabBarTableViewCell" bundle:nil] forCellReuseIdentifier:@"MoreTabBarTableViewCell"];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 120;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MoreTabBarTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MoreTabBarTableViewCell" forIndexPath:indexPath];
[cell setMoreTableValues];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath{
[_currentTableViewDelegate tableView:tableView didSelectRowAtIndexPath:indexPath];
}
@end
Gracias a Desconocido . Siguiendo su solución, pondré su código en Swift. Solo lo que debe hacer más es crear la clase MoreTableViewCell y simplemente hacerlo. No tienes que usar Storyboard. Si desea modificar tableView, puede hacerlo en el método customizeMoreTableView.
class TabBarMenuController: UITabBarController, UITableViewDelegate, UITableViewDataSource{
var tabBarItems: [UIViewController] = []
var areMessagesVisible: Bool = false
var titleForTabBars: [String] = ["resources", "events", "training", "my profile", "news", "contacts"]
var iconNames: [String] = ["film", "calendar", "classroom", "profile", "news", "Phone"]
var controllersStoryboardId: [String] = ["resourcesNavController", "eventsNavController", "enablementNavController", "profileNavController", "newsNavController", "contactsNavController"]
// to manage moreTableView
var moreTableView: UITableView = UITableView()
var currentTableViewDelegate: UITableViewDelegate?
override func viewDidLoad() {
super.viewDidLoad()
self.customizeMoreTableView()
//to REMOVE
areMessagesVisible = true
if !areMessagesVisible{
self.titleForTabBars.removeAtIndex(4)
self.controllersStoryboardId.removeAtIndex(4)
self.iconNames.removeAtIndex(4)
}
for i in 0 ..< controllersStoryboardId.count{
tabBarItems.append(UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier(controllersStoryboardId[i]) as? UINavigationController ?? UINavigationController())
}
self.moreNavigationController.navigationBar.tintColor = UIColor.blackColor()
}
override func viewWillAppear(animated: Bool) {
for i in 0 ..< tabBarItems.count{
tabBarItems[i].tabBarItem = UITabBarItem(title: titleForTabBars[i], image: UIImage(named: iconNames[i]), selectedImage: UIImage(named: iconNames[i]))
}
self.viewControllers = tabBarItems
}
func customizeMoreTableView(){
moreTableView = self.moreNavigationController.topViewController!.view as? UITableView ?? UITableView()
currentTableViewDelegate = moreTableView.delegate;
moreTableView.delegate = self
moreTableView.dataSource = self;
moreTableView.registerClass(MoreTableViewCell.self, forCellReuseIdentifier: "MoreTableViewCell")
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let moreCell = tableView.dequeueReusableCellWithIdentifier("MoreTableViewCell", forIndexPath: indexPath) as? MoreTableViewCell ?? MoreTableViewCell()
moreCell.textLabel?.text = titleForTabBars[indexPath.row + 4]
moreCell.imageView?.image = UIImage(named: iconNames[indexPath.row + 4])
/*let testLabel: UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 40))
testLabel.backgroundColor = UIColor.yellowColor()
moreCell.addSubview(testLabel)
*/
return moreCell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titleForTabBars.count - 4
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
currentTableViewDelegate?.tableView!(tableView, didSelectRowAtIndexPath: indexPath)
}
}