So erstellen Sie eine benutzerdefinierte Bearbeitungsansicht in iOS7 UITableView mit Objective C wie Evernote oder Apple Reminders, während Sie nach links streichen. Ich habe versucht, eine benutzerdefinierte Bearbeitungszugriffsansicht festzulegen, dies hat jedoch nicht funktioniert.
Evernote-Bearbeitungsansicht:
Erinnerungsbearbeitungsansicht:
Mein aktueller Code lautet
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSLog(@"delete");
}
}
Ich habe versucht, das Problem zu lösen mit: (UITableViewController.h)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//make cell
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[view setBackgroundColor:[UIColor greenColor]];
//add Buttons to view
cell.editingAccessoryView = view;
return cell;
}
Und das gleiche mit: (UITableViewCell)
- (void)willTransitionToState:(UITableViewCellStateMask)state;
- (void)setEditing:(BOOL)editing animated:(BOOL)animated;
- (UIView*)editingAccessoryView;
Kopieren Sie einfach den unten stehenden Code!
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewRowAction *editAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"Clona" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
//insert your editAction here
}];
editAction.backgroundColor = [UIColor blueColor];
UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"Delete" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath){
//insert your deleteAction here
}];
deleteAction.backgroundColor = [UIColor redColor];
return @[deleteAction,editAction];
}
Swift 3
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let editAction = UITableViewRowAction(style: .normal, title: "Edit") { (rowAction, indexPath) in
//TODO: edit the row at indexPath here
}
editAction.backgroundColor = .blue
let deleteAction = UITableViewRowAction(style: .normal, title: "Delete") { (rowAction, indexPath) in
//TODO: Delete the row at indexPath here
}
deleteAction.backgroundColor = .red
return [editAction,deleteAction]
}
Swift 2.1
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let editAction = UITableViewRowAction(style: .Normal, title: "Edit") { (rowAction:UITableViewRowAction, indexPath:NSIndexPath) -> Void in
//TODO: edit the row at indexPath here
}
editAction.backgroundColor = UIColor.blueColor()
let deleteAction = UITableViewRowAction(style: .Normal, title: "Delete") { (rowAction:UITableViewRowAction, indexPath:NSIndexPath) -> Void in
//TODO: Delete the row at indexPath here
}
deleteAction.backgroundColor = UIColor.redColor()
return [editAction,deleteAction]
}
Hinweis: ab iOS 8
Sie können UITableViewRowAction
s backgroundColor
verwenden, um ein benutzerdefiniertes Bild oder eine Ansicht festzulegen. Der Trick ist UIColor(patternImage:)
.
Grundsätzlich wird die Breite der UITableViewRowAction
-Fläche durch den Titel bestimmt. Sie können also die genaue Länge des Titels (oder Whitespace) ermitteln und die genaue Größe des Bildes mit patternImage
einstellen.
Um dies zu implementieren, habe ich die Erweiterungsmethode einer UIView
erstellt.
func image() -> UIImage {
UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0)
guard let context = UIGraphicsGetCurrentContext() else {
return UIImage()
}
layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
und eine Zeichenfolge mit Leerzeichen und exakter Länge zu machen,
fileprivate func whitespaceString(font: UIFont = UIFont.systemFont(ofSize: 15), width: CGFloat) -> String {
let kPadding: CGFloat = 20
let mutable = NSMutableString(string: "")
let attribute = [NSFontAttributeName: font]
while mutable.size(attributes: attribute).width < width - (2 * kPadding) {
mutable.append(" ")
}
return mutable as String
}
und jetzt können Sie UITableViewRowAction
erstellen.
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let whitespace = whitespaceString(width: kCellActionWidth)
let deleteAction = UITableViewRowAction(style: .`default`, title: whitespace) { (action, indexPath) in
// do whatever you want
}
// create a color from patter image and set the color as a background color of action
let kActionImageSize: CGFloat = 34
let view = UIView(frame: CGRect(x: 0, y: 0, width: kCellActionWidth, height: kCellHeight))
view.backgroundColor = UIColor.white
let imageView = UIImageView(frame: CGRect(x: (kCellActionWidth - kActionImageSize) / 2,
y: (kCellHeight - kActionImageSize) / 2,
width: 34,
height: 34))
imageView.image = UIImage(named: "x")
view.addSubview(imageView)
let image = view.image()
deleteAction.backgroundColor = UIColor(patternImage: image)
return [deleteAction]
}
Das Ergebnis wird so aussehen.
Eine andere Möglichkeit ist, den benutzerdefinierten Zeichensatz zu importieren, dessen Bild als Zeichensatz verwendet werden soll, und UIButton.appearance
verwenden. Dies wirkt sich jedoch auch auf andere Schaltflächen aus, sofern Sie die Schriftart der anderen Schaltflächen nicht manuell festlegen.
Ab iOS 11 wird diese Nachricht [TableView] Setting a pattern color as backgroundColor of UITableViewRowAction is no longer supported.
angezeigt. Momentan funktioniert es immer noch, aber es wird im zukünftigen Update nicht funktionieren.
Siehe folgenden Link: https://github.com/TeehanLax/UITableViewCell-Swipe-for-Options
Und passen Sie Ihre uitableviewcell mit mehreren Tasten an.
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
scrollView.contentSize = CGSizeMake(CGRectGetWidth(self.bounds) + kCatchWidth, CGRectGetHeight(self.bounds));
scrollView.delegate = self;
scrollView.showsHorizontalScrollIndicator = NO;
[self.contentView addSubview:scrollView];
self.scrollView = scrollView;
UIView *scrollViewButtonView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.bounds) - kCatchWidth, 0, kCatchWidth, CGRectGetHeight(self.bounds))];
self.scrollViewButtonView = scrollViewButtonView;
[self.scrollView addSubview:scrollViewButtonView];
// Set up our two buttons
UIButton *moreButton = [UIButton buttonWithType:UIButtonTypeCustom];
moreButton.backgroundColor = [UIColor colorWithRed:0.78f green:0.78f blue:0.8f alpha:1.0f];
moreButton.frame = CGRectMake(0, 0, kCatchWidth / 3.0f, CGRectGetHeight(self.bounds));
[moreButton setTitle:@"More" forState:UIControlStateNormal];
[moreButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[moreButton addTarget:self action:@selector(userPressedMoreButton:) forControlEvents:UIControlEventTouchUpInside];
[self.scrollViewButtonView addSubview:moreButton];
UIButton *shareButton = [UIButton buttonWithType:UIButtonTypeCustom];
shareButton.backgroundColor = [UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:1.0f];
shareButton.frame = CGRectMake(kCatchWidth / 3.0f, 0, kCatchWidth / 3.0f, CGRectGetHeight(self.bounds));
[shareButton setTitle:@"Share" forState:UIControlStateNormal];
[shareButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[shareButton addTarget:self action:@selector(userPressedMoreButton:) forControlEvents:UIControlEventTouchUpInside];
[self.scrollViewButtonView addSubview:shareButton];
UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
deleteButton.backgroundColor = [UIColor colorWithRed:1.0f green:0.231f blue:0.188f alpha:1.0f];
deleteButton.frame = CGRectMake(kCatchWidth / 3.0f+kCatchWidth / 3.0f, 0, kCatchWidth / 3.0f, CGRectGetHeight(self.bounds));
[deleteButton setTitle:@"Delete" forState:UIControlStateNormal];
[deleteButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[deleteButton addTarget:self action:@selector(userPressedDeleteButton:) forControlEvents:UIControlEventTouchUpInside];
[self.scrollViewButtonView addSubview:deleteButton];
UIView *scrollViewContentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
scrollViewContentView.backgroundColor = [UIColor whiteColor];
[self.scrollView addSubview:scrollViewContentView];
self.scrollViewContentView = scrollViewContentView;
UILabel *scrollViewLabel = [[UILabel alloc] initWithFrame:CGRectInset(self.scrollViewContentView.bounds, 10, 0)];
self.scrollViewLabel = scrollViewLabel;
[self.scrollViewContentView addSubview:scrollViewLabel];
Ich habe diesen Code mit meiner App umgesetzt und ein solches Ergebnis erhalten. Sie können die Anzahl der Schaltflächen in der Swipe-Zelle hinzufügen.
Hier werden Screenshots umgesetzt
Nach dem Wischen erscheinen die Schaltflächen der Zelle 3 "Mehr", "Teilen", "Löschen".
Sie können dies versuchen,
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let backView = UIView(frame: CGRect(x: 0, y: 0, width: 80, height: 80))
backView.backgroundColor = #colorLiteral(red: 0.933103919, green: 0.08461549133, blue: 0.0839477703, alpha: 1)
let myImage = UIImageView(frame: CGRect(x: 30, y: backView.frame.size.height/2-14, width: 16, height: 16))
myImage.image = #imageLiteral(resourceName: "rubbish-bin")
backView.addSubview(myImage)
let label = UILabel(frame: CGRect(x: 0, y: myImage.frame.Origin.y+14, width: 80, height: 25))
label.text = "Remove"
label.textAlignment = .center
label.textColor = UIColor.white
label.font = UIFont(name: label.font.fontName, size: 14)
backView.addSubview(label)
let imgSize: CGSize = tableView.frame.size
UIGraphicsBeginImageContextWithOptions(imgSize, false, UIScreen.main.scale)
let context = UIGraphicsGetCurrentContext()
backView.layer.render(in: context!)
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
let delete = UITableViewRowAction(style: .destructive, title: " ") { (action, indexPath) in
print("Delete")
}
delete.backgroundColor = UIColor(patternImage: newImage)
return [delete, share]
}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let delete = UITableViewRowAction(style: .Destructive, title: "Delete") { (action, indexPath) in
// delete item at indexPath
}
let share = UITableViewRowAction(style: .Normal, title: "Disable") { (action, indexPath) in
// share item at indexPath
}
share.backgroundColor = UIColor.blueColor()
return [delete, share]
}
Der obige Code zeigt, wie Sie benutzerdefinierte Buttons erstellen, wenn Sie in der Zeile streichen.
Dies unterstützt sowohl Titel als auch Bild.
Für iOS 11 und später:
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(
style: .normal,
title: "My Title",
handler: { (action, view, completion) in
//do what you want here
completion(true)
})
action.image = UIImage(named: "My Image")
action.backgroundColor = .red
let configuration = UISwipeActionsConfiguration(actions: [action])
configuration.performsFirstActionWithFullSwipe = false
return configuration
}
Eine ähnliche Methode ist auch für leadingSwipeActions
verfügbar.
Quelle:
https://developer.Apple.com/videos/play/wwdc2017/201/ (Spricht ungefähr um 16 Minuten darüber) https://developer.Apple.com/videos/play/wwdc2017/204 / (Spricht etwa 23 Minuten darüber)
Wenn Sie beim Durchführen von Wischaktionen nur Text verwenden möchten, können Sie die standardmäßigen Wischaktionen von iOS verwenden. Wenn Sie jedoch Bild und Text wünschen, müssen Sie ihn anpassen. Ich habe ein tolles Tutorial und ein Beispiel gefunden, das dieses Problem lösen kann.
Probieren Sie dieses Repository aus, um die benutzerdefinierte Swipe-Zelle zu erhalten. Sie können hier mehrere Optionen hinzufügen.
http://iosbucket.blogspot.in/2016/04/custom-swipe-table-view-cell_16.html
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
// action one
let editAction = UITableViewRowAction(style: .default, title: "Edit", handler: { (action, indexPath) in
print("Edit tapped")
self.myArray.add(indexPath.row)
})
editAction.backgroundColor = UIColor.blue
// action two
let deleteAction = UITableViewRowAction(style: .default, title: "Delete", handler: { (action, indexPath) in
print("Delete tapped")
self.myArray.removeObject(at: indexPath.row)
self.myTableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
})
deleteAction.backgroundColor = UIColor.red
// action three
let shareAction = UITableViewRowAction(style: .default, title: "Share", handler: { (action , indexPath)in
print("Share Tapped")
})
shareAction.backgroundColor = UIColor .green
return [editAction, deleteAction, shareAction]
}
erstellen Sie eine Ansicht in der benutzerdefinierten Zelle in der Tabellenansicht und wenden Sie PanGestureRecognizer auf die Ansicht in der Zelle an. Fügen Sie die Schaltflächen zur benutzerdefinierten Zelle hinzu. Wenn Sie die Ansicht in der benutzerdefinierten Zelle streichen, sind die Schaltflächen in der benutzerdefinierten Zelle sichtbar.
UIGestureRecognizer* recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
recognizer.delegate = self;
[YourView addGestureRecognizer:recognizer];
Und handhaben Sie das Verschieben der Ansicht in der Methode
if (recognizer.state == UIGestureRecognizerStateBegan) {
// if the gesture has just started, record the current centre location
_originalCenter = vwCell.center;
}
// 2
if (recognizer.state == UIGestureRecognizerStateChanged) {
// translate the center
CGPoint translation = [recognizer translationInView:self];
vwCell.center = CGPointMake(_originalCenter.x + translation.x, _originalCenter.y);
// determine whether the item has been dragged far enough to initiate / complete
_OnDragRelease = vwCell.frame.Origin.x < -vwCell.frame.size.width / 2;
}
// 3
if (recognizer.state == UIGestureRecognizerStateEnded) {
// the frame this cell would have had before being dragged
CGPoint translation = [recognizer translationInView:self];
if (_originalCenter.x+translation.x<22) {
vwCell.center = CGPointMake(22, _originalCenter.y);
IsvwRelease=YES;
}
CGRect originalFrame = CGRectMake(0, vwCell.frame.Origin.y,
vwCell.bounds.size.width, vwCell.bounds.size.height);
if (!_deleteOnDragRelease) {
// if the item is not being dragged far enough , snap back to the original location
[UIView animateWithDuration:0.2
animations:^{
vwCell.frame = originalFrame;
}
];
}
}
Ich denke, es ist nicht die beste Art, UIGestureRecognizer-basierte Zellen zu verwenden.
Erstens haben Sie keine Optionen für die Verwendung von CoreGraphics.
Perfekte Lösung, wird UIResponder oder eine UIGestureRecognizer
für die gesamte Tabellenansicht Nicht für jeden UITableViewCell
. Es wird Sie App stecken lassen.