Am o aplicație unde UITableView
's separator de insertie este setat la valori personalizate - Dreapta 0
, Plecat de la "0". Aceasta funcționează perfect în iOS 7.x, cu toate acestea, în
iOS 8.0` văd că separator de insertie este setat implicit de " 15 " pe dreapta. Chiar dacă în fișiere xib este setat la "0", se mai arată în mod incorect.
Cum pot elimina UITableViewCell
separator de margini?
iOS 8.0 introduce layoutMargins proprietate asupra celulelor ȘI punctele de vedere de masă.
Această proprietate este't disponibil pe iOS 7.0 astfel încât aveți nevoie pentru a asigurați-vă că verificați înainte de a atribui o!
Easy fix este de a subclasă tău mobil și trece peste aspectul marjele de proprietate cum a sugerat de către @user3570727. Cu toate acestea, veți pierde orice sistem comportament ca moștenirea marjele din Zona de Siguranță deci, eu nu recomand mai jos soluție:
(ObjectiveC)
-(UIEdgeInsets)layoutMargins {
return UIEdgeInsetsZero // override any margins inc. safe area
}
(swift 4.2):
override var layoutMargins: UIEdgeInsets { get { return .zero } set { } }
Dacă tu nu't doriți să suprascrieți proprietate, sau trebuie să-l setați condiționat, ține de lectură.
În plus față de `layoutMargins de proprietate, Apple a adăugat o proprietate în celula ta, care va preveni-l de la moștenirea ta Tabel's marja de setări. Când această proprietate este setată, celulele sunt permise pentru a configura propria lor marjele independent de tabel. Cred că de ea ca un by-pass.
Această proprietate se numește preservesSuperviewLayoutMargins
, și setarea-l la " NU " va permite celulei's layoutMargin
setare pentru a trece peste orice layoutMargin
este setat pe TableView. Ambele economisește timp (nu - 't trebuie să modificați Tabelul de Vedere's setări), și este mult mai concis. Vă rugăm să consultați Mike Abdullah's a răspunde pentru o explicație detaliată.
NOTĂ: ceea ce urmează este un curat punere în aplicare pentru un celula-nivelul marjei de setare, exprimată în Mike Abdullah's a răspunde. Setarea dvs. de mobil's preservesSuperviewLayoutMargins=NU
va asigura că Tabelul dvs. de Vedere să nu țină seama de setări de celule. Dacă vă doriți de fapt, întreaga masă de vedere pentru a fi în concordanță margini, vă rugăm să reglați codul corespunzător.
Configurare marjele celulare:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Remove seperator inset
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
// Prevent the cell from inheriting the Table View's margin settings
if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
[cell setPreservesSuperviewLayoutMargins:NO];
}
// Explictly set your cell's layout margins
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
Swift 4:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// Remove seperator inset
if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
cell.separatorInset = .zero
}
// Prevent the cell from inheriting the Table View's margin settings
if cell.responds(to: #selector(setter: UITableViewCell.preservesSuperviewLayoutMargins)) {
cell.preservesSuperviewLayoutMargins = false
}
// Explictly set your cell's layout margins
if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
cell.layoutMargins = .zero
}
}
Setarea preservesSuperviewLayoutMargins
proprietate pe mobil să NU *ar trebui să *** prevenirea masa dumneavoastră de vedere de imperative tău mobil margini. În unele cazuri, pare să nu funcționeze corespunzător.
Dacă tot nu reușește, puteți brute-force-ți Vezi Tabelul de marje:
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// Force your tableview margins (this may be a bad idea)
if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
}
Swift 4:
func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Force your tableview margins (this may be a bad idea)
if tableView.responds(to: #selector(setter: UITableView.separatorInset)) {
tableView.separatorInset = .zero
}
if tableView.responds(to: #selector(setter: UITableView.layoutMargins)) {
tableView.layoutMargins = .zero
}
}
...și acolo te duci! Acest lucru ar trebui să funcționeze pe iOS 7 și 8.
EDIT: Mohamed Saleh a adus în atenție o posibilă schimbare în iOS 9. Poate fi necesar să setați Tabelul de Vedere's cellLayoutMarginsFollowReadableWidth
a "NU", dacă doriți să personalizați introduceri sau margini. Kilometraj dvs. poate varia, acest lucru nu este documentat foarte bine.
Această proprietate există numai în iOS 9, astfel încât să fie sigur de a verifica, înainte de setare.
if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
myTableView.cellLayoutMarginsFollowReadableWidth = NO;
}
Swift 4:
if myTableView.responds(to: #selector(setter: self.cellLayoutMarginsFollowReadableWidth)) {
myTableView.cellLayoutMarginsFollowReadableWidth = false
}
(codul de mai sus https://stackoverflow.com/questions/25770119/ios-8-uitableview-separator-inset-0-not-working/32860532#32860532)
EDIT: Aici's o pură Interface Builder abordare:
NOTĂ: iOS 11 modificări & simplifică mult de acest comportament, o actualizare va fi viitoarea...
Las's ia un moment pentru a înțelege problema înainte orbește de încărcare în a încerca să-l repara.
O scurtă scormoni în debugger vă va spune că separator de linii sunt subviews de UITableViewCell`. Se pare că celula în sine are o valoare justă de responsabilitate pentru structura de aceste linii.
iOS 8 a fost introdus conceptul de layout marjele. În mod implicit, un punct de vedere's layout marjele sunt `8pt pe toate părțile, și-au're moștenit de la strămoșul vedere.
Cât de bine putem spune, atunci când de stabilire sale separator de linie, UITableViewCell
alege să respecte stânga layout marja, folosind-o pentru a constrânge plecat de insertie.
Pune totul împreună, pentru a atinge dorit insertie de situare cu adevărat de la zero, trebuie să:
Pune-așa, l's o sarcina destul de simplu pentru a obține:
cell.layoutMargins = UIEdgeInsetsZero;
cell.preservesSuperviewLayoutMargins = NO;
Lucruri de reținut:
, ai _can_ configura strămoș vedere (cum ar fi masa), pentru a avea
0` marginea din stânga, dar acest lucru pare în mod inerent mai predispuse la erori ca tu nu't de control că întreaga ierarhie.UITableView
atrage în partea de jos a câmpiei stil mese, am'm ghicitul că va solicita specificarea aceleași setări la nivel de masă prea (am't incercat asta!)Cred că aceasta este aceeași întrebare pe care am pus aici: https://stackoverflow.com/questions/25762723/remove-separatorinset-on-ios-8-uitableview-for-xcode-6-iphone-simulator
În iOS 8, există o nouă proprietate pentru toate obiectele moștenesc de la UIView
. Deci, soluția pentru a seta `SeparatorInset în iOS 7.x nu va fi capabil de a elimina spațiu alb vezi pe UITableView în iOS 8.
Noua proprietate este numit "layoutMargins".
@property(nonatomic) UIEdgeInsets layoutMargins
Description The default spacing to use when laying out content in the view.
Availability iOS (8.0 and later)
Declared In UIView.h
Reference UIView Class Reference
Soluția:-
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[tableView setLayoutMargins:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
Dacă ați setat telefonul.layoutMargins = UIEdgeInsetsZero;fără a verifica dacă
layoutMarginsexistă, cererea se va prăbuși pe iOS 7.x. Deci, cel mai bun mod ar fi verificarea dacă
layoutMarginsexistă în primul rând înainte de
setLayoutMargins:UIEdgeInsetsZero`.
Puteți utiliza UIAppearance o dată, la pornire de aplicare (înainte UI este încărcat), să-l setați ca implicit setările globale:
// iOS 7:
[[UITableView appearance] setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[[UITableView appearance] setSeparatorInset:UIEdgeInsetsZero];
[[UITableViewCell appearance] setSeparatorInset:UIEdgeInsetsZero];
// iOS 8:
if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) {
[[UITableView appearance] setLayoutMargins:UIEdgeInsetsZero];
[[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
[[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];
}
În acest fel, vă păstrați UIViewController's cod curat și întotdeauna poate trece peste asta, dacă vrei.
iOS introduce layoutMargins proprietate asupra celulelor ȘI punctele de vedere de masă.
Această proprietate este't disponibil în iOS 7.0 astfel încât aveți nevoie pentru a asigurați-vă că verificați înainte de a atribui o!
Cu toate acestea, Apple a adăugat o proprietate numit preservesSuperviewLayoutMargins în celula ta, care va preveni-l de la moștenirea ta Tabel's marja de setări. În acest fel, celulele pot configura propria lor marjele independent de tabel. Cred că de ea ca un by-pass.
Această proprietate se numește preservesSuperviewLayoutMargins, iar setarea NU poate permite să suprascrie Tabel's layoutMargin setări cu propriile celule's layoutMargin setare. Ambele economisește timp (nu - 't trebuie să modificați Tabelul de Vedere's setări), și este mult mai concis. Vă rugăm să consultați Mike Abdullah's a răspunde pentru o explicație detaliată.
NOTĂ: aceasta este buna, mai puțin murdar de implementare, așa cum este exprimată în Mike Abdullah's a răspuns, setarea dvs. de mobil's preservesSuperviewLayoutMargins=NU va asigura că Tabelul dvs. de Vedere să nu țină seama de setări de celule.
Primul pas - Setup tău mobil margini:
/*
Tells the delegate that the table view is about to draw a cell for a particular row.
*/
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
forRowAtIndexPath indexPath: NSIndexPath)
{
// Remove separator inset
if cell.respondsToSelector("setSeparatorInset:") {
cell.separatorInset = UIEdgeInsetsZero
}
// Prevent the cell from inheriting the Table View's margin settings
if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
cell.preservesSuperviewLayoutMargins = false
}
// Explictly set your cell's layout margins
if cell.respondsToSelector("setLayoutMargins:") {
cell.layoutMargins = UIEdgeInsetsZero
}
}
Setarea preservesSuperviewLayoutMargins proprietate pe mobil să NU *ar trebui să *** prevenirea masa dumneavoastră de vedere de imperative tău mobil margini. În unele cazuri, aceasta nu pare să funcționeze corect.
A doua etapă - Doar dacă tot nu reușește, puteți brute-force-ți Vezi Tabelul de marje:
/*
Called to notify the view controller that its view has just laid out its subviews.
*/
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Force your tableview margins (this may be a bad idea)
if self.tableView.respondsToSelector("setSeparatorInset:") {
self.tableView.separatorInset = UIEdgeInsetsZero
}
if self.tableView.respondsToSelector("setLayoutMargins:") {
self.tableView.layoutMargins = UIEdgeInsetsZero
}
}
...și acolo te duci! Acest lucru ar trebui să funcționeze pe iOS 8, precum și iOS 7.
Notă: testat folosind iOS 8.1 și 7.1, în cazul meu, am nevoie doar de a utiliza primul pas din această explicație.
Al Doilea Pas este necesar doar dacă aveți nepopulate celulă sub prestate de celule, de exemplu. dacă masa este mai mare decât numărul de rânduri din tabelul de model. Nu face al doilea pas ar duce la diferite separator compensează.
În Swift-l's ușor mai enervant, deoarece layoutMargins
este o proprietate, astfel încât să aveți pentru a trece peste getter și setter.
override var layoutMargins: UIEdgeInsets {
get { return UIEdgeInsetsZero }
set(newVal) {}
}
Acest lucru va face ca layoutMargins
readonly, care în cazul meu este bine.
Pentru iOS 9, trebuie să adăugați:
if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
myTableView.cellLayoutMarginsFollowReadableWidth = NO;
}
Pentru mai multe detalii vă rugăm să consultați întrebare.
Swift 2.0 Extensie
Am vrut doar să împărtășesc o extensie-am făcut pentru a elimina marjele de tableview separatoare pentru celule.
extension UITableViewCell {
func removeMargins() {
if self.respondsToSelector("setSeparatorInset:") {
self.separatorInset = UIEdgeInsetsZero
}
if self.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
self.preservesSuperviewLayoutMargins = false
}
if self.respondsToSelector("setLayoutMargins:") {
self.layoutMargins = UIEdgeInsetsZero
}
}
}
Folosit în context:
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
cell.removeMargins()
return cell
Swift:
override func viewDidLoad() {
super.viewDidLoad()
if self.tableView.respondsToSelector("setSeparatorInset:") {
self.tableView.separatorInset = UIEdgeInsetsZero
}
if self.tableView.respondsToSelector("setLayoutMargins:") {
self.tableView.layoutMargins = UIEdgeInsetsZero
}
self.tableView.layoutIfNeeded() // <--- this do the magic
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
...
if cell.respondsToSelector("setSeparatorInset:") {
cell.separatorInset = UIEdgeInsetsZero
}
if cell.respondsToSelector("setLayoutMargins:") {
cell.layoutMargins = UIEdgeInsetsZero
}
return cell
}
Ca ceea ce cdstamper sugerat în loc de masa de vedere, adăugarea de mai jos linii în celulă's layoutSubview metodă funcționează pentru mine.
- (void)layoutSubviews
{
[super layoutSubviews];
if ([self respondsToSelector:@selector(setSeparatorInset:)])
[self setSeparatorInset:UIEdgeInsetsZero];
if ([self respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)])
{
[self setPreservesSuperviewLayoutMargins:NO];;
}
if ([self respondsToSelector:@selector(setLayoutMargins:)])
{
[self setLayoutMargins:UIEdgeInsetsZero];
}
}
Swift 3.0 exemplu:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// removing seperator inset
if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
cell.separatorInset = .zero
}
// prevent the cell from inheriting the tableView's margin settings
if cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins)) {
cell.preservesSuperviewLayoutMargins = false
}
// explicitly setting cell's layout margins
if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
cell.layoutMargins = .zero
}
}
Aici's singura modalitate de a controla pe deplin chestia asta (pe care am putut găsi)
Pentru a controla pe deplin ambele separator introduceri și layout marjelor pe fiecare celulă. Face acest lucru în anii willDisplayCell
metoda pe UITableviewDelegate
.
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
cell.layoutMargins = UIEdgeInsetsZero
cell.contentView.layoutMargins = UIEdgeInsetsMake(0, 10, 0, 10)
cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)
}
Celula obiect controlează separator, și contentView
controleaza totul altceva. Dacă separatorul de insertie spații sunt afișate într-o culoare neașteptată acest lucru ar trebui să rezolve:
cell.backgroundColor = cell.contentView.backgroundColor
O soluție simplă în Rapid pentru iOS 8 cu un custom UITableViewCell
override func awakeFromNib() {
super.awakeFromNib()
self.layoutMargins = UIEdgeInsetsZero
self.separatorInset = UIEdgeInsetsZero
}
În acest fel vă sunt setarea layoutMargin " și " separatorInsetdoar o singură dată, în loc de a face asta pentru fiecare
willDisplayCell` ca cele mai multe dintre raspunsurile de mai sus sugerează.
Dacă utilizați un custom UITableViewCell
aici e locul potrivit să o facă.
În caz contrar, ar trebui să o faci în tableView:cellForRowAtIndexPath`.
Doar un indiciu: nu't nevoie pentru a seta preservesSuperviewLayoutMargins = false
, deoarece valoarea implicită este deja "NU"!
Trebuie doar să adăugați codul de mai jos poate rezolva acest program.
Mult noroc pentru tine!
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
Lukasz răspuns în Swift:
// iOS 7:
UITableView.appearance().separatorStyle = .SingleLine
UITableView.appearance().separatorInset = UIEdgeInsetsZero
UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero
// iOS 8:
if UITableView.instancesRespondToSelector("setLayoutMargins:") {
UITableView.appearance().layoutMargins = UIEdgeInsetsZero
UITableViewCell.appearance().layoutMargins = UIEdgeInsetsZero
UITableViewCell.appearance().preservesSuperviewLayoutMargins = false
}
Acesta este codul care's de lucru pentru mine, în Swift:
override func viewDidLoad()
{
super.viewDidLoad()
...
if tableView.respondsToSelector("setSeparatorInset:") {
tableView.separatorInset = UIEdgeInsetsZero
}
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath)
{
if cell.respondsToSelector("setSeparatorInset:") {
cell.separatorInset.left = CGFloat(0.0)
}
if tableView.respondsToSelector("setLayoutMargins:") {
tableView.layoutMargins = UIEdgeInsetsZero
}
if cell.respondsToSelector("setLayoutMargins:") {
cell.layoutMargins.left = CGFloat(0.0)
}
}
Acest lucru pare cel mai curat pentru mine (pentru moment), ca toate celule/tableView edge/marja de ajustări sunt efectuate în tableView:willDisplayCell:forRowAtIndexPath:metoda, fără bucherie inutile codul în tableView:cellForRowAtIndexPath:
.
Btw, am'm numai stabilirea mobil's a lăsat separatorInset/layoutMargins, pentru că în acest caz nu't vrei să-mi strici constrângeri care am înființat în celula mea.
Cod actualizat pentru a Swift 2.2 :
override func viewDidLoad() {
super.viewDidLoad()
if tableView.respondsToSelector(Selector("setSeparatorInset:")) {
tableView.separatorInset = UIEdgeInsetsZero
}
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) {
if cell.respondsToSelector(Selector("setSeparatorInset:")) {
cell.separatorInset.left = CGFloat(0.0)
}
if tableView.respondsToSelector(Selector("setLayoutMargins:")) {
tableView.layoutMargins = UIEdgeInsetsZero
}
if cell.respondsToSelector(Selector("setLayoutMargins:")) {
cell.layoutMargins.left = CGFloat(0.0)
}
}
Cele mai multe răspunsuri sunt afișate separator introduceri și layout marjele de a fi stabilit pe o varietate de metode (de exemplu, viewDidLayoutSubviews
, willDisplayCell
, etc) pentru celule și tableviews, dar am'am constatat că doar punând aceste in cellForRowAtIndexPath
mare de lucrări. Se pare ca cel mai curat mod.
// kill insets for iOS 8
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) {
cell.preservesSuperviewLayoutMargins = NO;
[cell setLayoutMargins:UIEdgeInsetsZero];
}
// iOS 7 and later
if ([cell respondsToSelector:@selector(setSeparatorInset:)])
[cell setSeparatorInset:UIEdgeInsetsZero];