ios - uitableviewcell - uitableviewcontroller
La propiedad tableFooterView no repara el pie de página en la parte inferior de la vista de tabla (9)
Como su objetivo es tener un pie de página que permanezca fijo en la parte inferior de la pantalla, y no desplazarse con la tabla, entonces no puede usar un pie de página de la vista de tabla. De hecho, ni siquiera puedes usar un UITableViewController
.
Debe implementar su controlador de vista como un UIViewController
. Luego, agrega su propia vista de tabla como subvista. También agrega su pie de página como una subvista de la vista del controlador de vista, no de la vista de tabla. Asegúrese de ajustar el tamaño de la vista de tabla para que su parte inferior esté en la parte superior de la vista del pie de página.
Tendrá que hacer que su controlador de vista se ajuste a los protocolos UITableViewDataSource
y UITableViewDelegate
y conectar todo para replicar la funcionalidad de UITableViewController
.
Estoy configurando una vista de pie de página en el método viewDidLoad:
UIView *fView = [[UIView alloc] initWithFrame:CGRectMake(0, 718, 239, 50)];
fView.backgroundColor =[UIColor yellowColor];
self.table.tableFooterView = fView;
Desafortunadamente, el pie de página no está dibujando en el especificado (x,y)
especificado anteriormente, sino que se adhiere a las celdas, por lo que si la vista de tabla tiene 4 celdas, el pie de página se dibujará en la quinta celda.
Incluso probé el método de protocolo, tableView:viewForFooterInSection
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
UIView *fView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 239, 50)];
fView.backgroundColor =[UIColor yellowColor];
return fView;
}
el problema no se resuelve, estoy seguro de que la propiedad tableFooterView
debería fi fi tableFooterView
en la vista del pie de página en la parte inferior de la vista de tabla, pero no estoy seguro de qué es lo que me puede faltar aquí. Gracias por adelantado.
La siguiente es la solución para este problema de pie de página, cuando NO queremos que el pie de página se pegue en el fondo todo el tiempo, AKA. solo se pega a la parte inferior cuando no hay suficientes filas para llenar la pantalla, o cuando el usuario se desplaza completamente hacia abajo de la pantalla.
Agregue su self.footerView
a su self.tableView
como una subvista en -viewDidLoad:
o en algún lugar como ese, luego configure el delegado para self.tableView
, actualice el recuadro de contenido de la tabla vista a self.tableView.contentInset = UIEdgeInsetsMake(0, 0, CGRectGetHeight(self.footerView), 0);
y configure los siguientes métodos:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self updateFooterView];
}
- (void)updateFooterView
{
CGRect sectionFrame = [self.tableView rectForSection:0];
CGFloat bottomSpace = self.tableView.contentOffset.y + CGRectGetHeight(self.tableView.frame) - CGRectGetMaxY(sectionFrame);
CGFloat footerHeight = CGRectGetHeight(self.footerView.frame);
CGFloat transformY = self.tableView.contentOffset.y + footerHeight - MIN(bottomSpace,footerHeight);
CGRect footerFrame = self.footerView.frame;
footerFrame.origin.y = self.tableView.bounds.size.height - footerFrame.size.height + transformY;
self.footerView.frame = footerFrame;
}
Siempre que necesite actualizar el pie de página (es decir, después de agregar una nueva fila), simplemente llame a -updateFooterView
y usted debe estar bien.
Logré que se fijara una etiqueta en la parte inferior de mi UITableViewController estático. No es la solución perfecta para todos los escenarios, pero funcionó para mis necesidades simples.
UIView* v = [[UIView alloc] initWithFrame:self.view.bounds];
CGFloat labelHeight = 30;
CGFloat padding = 5;
UILabel* l = [[UILabel alloc] initWithFrame:CGRectMake(0, v.frame.size.height - labelHeight - padding, self.view.frame.size.width, labelHeight)];
l.text = @"Hello World";
[v addSubview:l];
[self.tableView setBackgroundView:v];
Otra forma es usar UITableViewController
en un guión gráfico e incrustarlo en un UIViewController como una vista de contenedor. Luego puede usar el diseño automático para establecer la relación entre el pie de página y la vista del contenedor que contiene la UITableView
Parece que algo similar a lo siguiente funciona bastante bien:
import PlaygroundSupport
import UIKit
let testVC = UITableViewController(style: .grouped)
testVC.view.frame = CGRect(x: 0, y: 0, width: 400, height: 700)
testVC.view.backgroundColor = .white
class TableViewDataSourceDelegate : NSObject {
var rows = 2
}
extension TableViewDataSourceDelegate : UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rows
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
cell.backgroundColor = .red
return cell
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
let tableViewHeight = tableView.bounds.size.height
let varticalMargin: CGFloat
if #available(iOS 11.0, *) {
varticalMargin = tableView.directionalLayoutMargins.bottom + tableView.directionalLayoutMargins.top
} else {
varticalMargin = tableView.layoutMargins.bottom + tableView.layoutMargins.top
}
let verticalInset: CGFloat
if #available(iOS 11.0, *) {
verticalInset = tableView.adjustedContentInset.bottom + tableView.adjustedContentInset.top
} else {
verticalInset = tableView.contentInset.bottom + tableView.contentInset.top
}
let tableViewContentHeight = tableView.contentSize.height - varticalMargin
let height: CGFloat
if #available(iOS 11.0, *) {
let verticalSafeAreaInset = tableView.safeAreaInsets.bottom + tableView.safeAreaInsets.top
height = tableViewHeight - tableViewContentHeight - verticalInset - verticalSafeAreaInset
} else {
height = tableViewHeight - tableViewContentHeight - verticalInset
}
if (height < 0) {
return 0
} else {
return height
}
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let extraButtonSpace = UIView()
extraButtonSpace.backgroundColor = .clear
return extraButtonSpace
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
tableView.beginUpdates()
rows += 1
tableView.insertRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
} else if indexPath.row == 1 {
tableView.beginUpdates()
rows -= 1
tableView.deleteRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
} else {
tableView.beginUpdates()
tableView.endUpdates()
}
}
}
let controller = TableViewDataSourceDelegate()
testVC.tableView.delegate = controller
testVC.tableView.dataSource = controller
testVC.tableView.reloadData()
let extraButtonSpace = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 80))
extraButtonSpace.backgroundColor = .yellow
testVC.tableView.tableFooterView = extraButtonSpace
PlaygroundPage.current.liveView = testVC.view
Puede usar esto para hacer que la tabla parezca más pequeña según la cantidad de filas que tenga:
let tblView = UIView(frame: CGRectZero)
tableView.tableFooterView = tblView
tableView.tableFooterView!.hidden = true
tableView.backgroundColor = UIColor.clearColor()
Otra alternativa sería cambiar la altura de la fila en la ruta del índice dependiendo de en qué número de filas mínimas tiene ese problema.
Si desea fijar el pie de página en la parte inferior, debe crear footerView personalizado y cambiar el marco de pie de página cuando el tamaño del contenido de tableView esté cambiando:
-(void)changeCustomTableFooterYPositionWithTableFrame:(CGRect)tableFrame tableContentSize: (CGSize) tableContentSize {
CGFloat originalTableViewTopEdgeInset = self.tableView.contentInset.top;
CGFloat originalTableViewBottomEdgeInset = self.tableView.contentInset.bottom - self.tableFooterView.frame.size.height;
CGFloat footerViewYPositionByContentSize = tableContentSize.height;
CGFloat footerViewYPositionByTableSize = tableFrame.size.height - self.tableFooterView.frame.size.height - originalTableViewTopEdgeInset - originalTableViewBottomEdgeInset;
CGFloat tableFooterViewYPosition = MAX(footerViewYPositionByContentSize, footerViewYPositionByTableSize);
self.tableFooterView.frame = CGRectMake(self.tableFooterView.frame.origin.x, tableFooterViewYPosition, self.customTableFooterView.frame.size.width, self.customTableFooterView.frame.size.height);
}
Para detectar cuándo se modificó contentSize, agregue el observador a contentSize:
[self addObserver: self forKeyPath: @"tableView.contentSize" options: NSKeyValueObservingOptionNew + NSKeyValueObservingOptionOld context: ContentSizeContext];
No olvides cambiar tableView.edgeInsets al insertar el pie de página:
self.tableView.contentInset = UIEdgeInsetsMake(self.tableView.contentInset.top, self.tableView.contentInset.left, self.tableView.contentInset.bottom + self.customTableFooterView.frame.size.height, self.tableView.contentInset.right);
Puede ver la clase heredada y el ejemplo en el siguiente enlace: TableViewWithFooterAtBottom
Si la vista de tabla o el controlador de vista de tabla están envueltos por un controlador de navegación, considere usar la barra de UITo del controlador de navegación. Siempre se pegará al fondo.
[self.navigationController setToolbarHidden:NO];
Siempre se agregará una vista de pie de página al final del contenido.
Esto significa que se agregará un pie de página de sección debajo de las celdas de una sección, una vista de pie de tabla al pie de todas las secciones, independientemente de la posición que establezca en su vista.
Si desea agregar un contenido "estático", debería considerar agregar una vista fuera de la vista de tabla (superview), lo que no es posible si usa UITableViewController
, o si usa [self.table addSubView:view]
y ajusta el colocar / transformar a la propiedad contentOffset
la vista de contentOffset
en el método scrollViewDidScroll:
delegate ( UITableView
es una subclase de UIScrollView
para que también reciba sus llamadas de delegado) como en este código:
@implementation YourTableViewController {
__weak UIView *_staticView;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIView *staticView = [[UIView alloc] initWithFrame:CGRectMake(0, self.tableView.bounds.size.height-50, self.tableView.bounds.size.width, 50)];
staticView.backgroundColor = [UIColor redColor];
[self.tableView addSubview:staticView];
_staticView = staticView;
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
_staticView.transform = CGAffineTransformMakeTranslation(0, scrollView.contentOffset.y);
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
// this is needed to prevent cells from being displayed above our static view
[self.tableView bringSubviewToFront:_staticView];
}
...