写在开头:本文所介绍的方法使用的是iOS8-10中的API,不过支持在iOS11上运行。之后会写一篇介绍如何用iOS11的新API来实现,到时通知大家。(2017-08-16)
本文介绍两种UITableView左滑菜单的实现方法,1. 默认, 2. 自定义。效果如下:
1. 系统默认效果
swipe-default.PNG2. 自定义图标效果 (类似“邮件”应用)
swipe-customize-1.PNG
目录:
- 系统默认图标实现方法
- 自定义图标实现方法 a. 自定义多个左滑菜单选项 b. 自定义左滑选项外观 UITableView视图层级(iOS8-10, 11) 具体实现方法 (支持iOS8-10, 11)
- TableCell上有其他按钮的处理方法
1. 系统默认图标实现方法
如果只需要使用默认图标,只需要在对应的TableViewController里实现数据源方法tableView:commitEditingStyle:forRowAtIndexPath就行了:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { [self removeAction:indexPath.section]; // 在此处自定义删除行为 } else { DEBUG_OUT(@"Unhandled editing style: %ld", (long) editingStyle); } }向左滑动table cell,该cell会自动进入编辑模式(cell.isEditing = 1),并在右边出现删除按钮,红底白字,按钮上的文字会根据系统语言自动改变;点击该按钮则触发commitEditingStyle执行相应的动作。
如果不进行自定义,默认的左滑菜单只会有一个按钮,不过按钮上的文字可以用随意进行更改,按钮的宽度会根据文字标题长度自动调整,需要自己支持多语言:
效果如下:- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath { return @"想写什么都行"; }change-title.PNGPS:如果除了文字内容外,还想调整其它,比如文字颜色,背景颜色,选项的宽高等,则可以拿到对应的UIButton以后直接修改,具体方法参照本文2) b部分。
2. 自定义图标实现方法
我认为自定义又分为两个层次: a. 自定义多个左滑菜单选项 和 b. 自定义左滑选项外观 .
a. 自定义多个左滑菜单选项
如果需要超过一个左滑选项,需要实现代理方法tableView:editActionsForRowAtIndexPath,在里面创建多个UITableViewRowAction:
- (NSArray*)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { // delete action UITableViewRowAction *deleteAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:NSLocalizedString(@"DeleteLabel", @"") handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { [tableView setEditing:NO animated:YES]; // 这句很重要,退出编辑模式,隐藏左滑菜单 [self removeNotificationAction:index]; }]; // read action // 根据cell当前的状态改变选项文字 NSInteger index = indexPath.section; BOOL isRead = [[NotificationManager instance] read:index]; NSString *readTitle = isRead ? @"Unread" : @"Read"; // 创建action UITableViewRowAction *readAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:readTitle handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { [tableView setEditing:NO animated:YES]; // 这句很重要,退出编辑模式,隐藏左滑菜单 [[NotificationManager instance] setRead:!isRead index:index]; }]; return @[deleteAction, readAction]; }可以看到这里我们创建了delete和read两个action。这是因为实现了该方法以后,1) 中用的commitEditingStyle:forRowAtIndexPath就不会被触发了,所以删除按钮也需要自己定义。
[tableView setEditing:NO animated:YES]; 这一行代码很重要,它的效果是在点击之后退出编辑模式,关闭左滑菜单。如果忘了加这一句的话,即使点击了按钮cell也不会还原。在1) 中使用默认模式的时候,系统会自动帮我们调用这一句,现在则需要手动调用。
对创建并返回的每个action,apple library会自动帮我们生成一个对应按钮,配置好基本的交互,并添加到左滑菜单中。
效果如下:two-actions-2.PNG上图我们对两个action都指定了UITableViewRowActionStyleNormal(灰底白字),不过其实有几种不同的预设外观 (不要问我为啥有两个都是红底白字。。。)
UITableViewRowActionStyleNormal:灰底白字
UITableViewRowActionStyleDefault:红底白字
UITableViewRowActionStyleDestructive:红底白字我们还可以更改action button的背景色,在创建action的时候添加一行代码即可:
效果如下:deleteAction.backgroundColor = [UIColor orangeColor]; readAction.backgroundColor = [UIColor blueColor];change-background-2.PNG
2b. 自定义左滑选项外观
自定义左滑选项外观的资料很少,我做的时候找得相当辛苦。不过后来理解了UITableView的视图层级,一切就变得很简单了。
UITableView视图层级(iOS8-10, 11)
和iOS8-10相比,iOS11的左滑选项的视图层级有了较大改变。最显著的改变是从是UITableViewCell的子视图变成了UITableView的子视图。总结一下就是:
iOS 8-10: UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView -> _UITableViewCellActionButton
iOS 11 (Xcode 8编译): UITableView -> UITableViewWrapperView -> UISwipeActionPullView -> UISwipeActionStandardButton
iOS 11 (Xcode 9编译): UITableView -> UISwipeActionPullView -> UISwipeActionStandardButton不想看原理的看到这里就可以直接跳到下面去看具体的实现方法了, 有兴趣看每一层具体有些什么的同学可以继续。
iOS8-10下的层级:
在tableView代理方法里设置断点打印发现,正常状态下cell上只有两个subview:
(lldb) po [tableCell subviews] <__NSArrayM 0x14de75670>( <UITableViewCellContentView: 0x14dd56940; frame = (0 0; 440 105); opaque = NO; gestureRecognizers = <NSArray: 0x14dd65ff0>; layer = <CALayer: 0x14dd56ac0>>, <_UITableViewCellSeparatorView: 0x14dd73810; frame = (15 154.5; 347 0.5); layer = <CALayer: 0x14dd736f0>> )而在左滑进入editing mode之后,就变成了3个,多出来一个 叫做UITableViewCellDeleteConfirmationView的子视图:
(lldb) po [tableCell subviews] <__NSArrayM 0x14de75670>( <UITableViewCellDeleteConfirmationView: 0x14de737d0; frame = (375 0; 0 105); clipsToBounds = YES; autoresize = H; animations = { bounds.origin=<CASpringAnimation: 0x14db56aa0>; bounds.size=<CASpringAnimation: 0x14db5b2e0>; position=<CASpringAnimation: 0x14db498e0>; bounds.origin-2=<CASpringAnimation: 0x14db8a3d0>; bounds.size-2=<CASpringAnimation: 0x14db26c10>; }; layer = <CALayer: 0x14de72fc0>>, <UITableViewCellContentView: 0x14dd56940; frame = (0 0; 375 105); opaque = NO; gestureRecognizers = <NSArray: 0x14dd65ff0>; layer = <CALayer: 0x14dd56ac0>>, <_UITableViewCellSeparatorView: 0x14dd73810; frame = (15 154.5; 347 0.5); layer = <CALayer: 0x14dd736f0>> )再进一步查看这个多出来的UITableViewCellDeleteConfirmationView的子视图,发现两个UIButton:
(lldb) po tableCell.subviews[0].subviews <__NSArrayM 0x14dea14c0>( <_UITableViewCellActionButton: 0x14de93ea0; frame = (71.5 0; 80.5 105); opaque = NO; autoresize = H; layer = <CALayer: 0x14de93150>>, <_UITableViewCellActionButton: 0x14de9d900; frame = (0 0; 71.5 105); opaque = NO; autoresize = H; layer = <CALayer: 0x14de9dbb0>> )最后再打印一下这两个UIButton的title,发现分别是“Read”和“Delete”。
也就是说,这两个UIButton,分别对应我们在a部分创建的两个UITableViewRowAction。所以我们只要遍历UITableViewCell的子视图,拿到对应UIButton的reference,什么修改高度,添加图片,修改字体,都是手到擒来。
iOS11下的层级 (用Xcode 8编译)
依然在tableView代理方法里设置断点打印发现,UITableViewCell下面没有UITableViewCellDeleteConfirmationView子视图了,不过在UITableViewWrapperView下面,多了一个UISwipeActionPullView。
(lldb) po self.tableView.subviews <__NSArrayM 0x1c0652cf0>( <UITableViewWrapperView: 0x105094200; frame = (0 0; 1000 1000); gestureRecognizers = <NSArray: 0x1c4457e50>; layer = <CALayer: 0x1c4224de0>; contentOffset: {0, 0}; contentSize: {1000, 1000}; adjustedContentInset: {0, 0, 0, 0}>, <UIImageView: 0x10466bb20; frame = (994.5 733; 2.5 220); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x1c0426900>> ) (lldb) po [self.tableView.subviews[0] subviews] <__NSArrayM 0x1c04457f0>( <UITableViewCell: 0x10e17d800; baseClass = UITableViewCell; frame = (0 277.5; 375 212.5); autoresize = W; layer = <CALayer: 0x1c0427c80>>, <: UITableViewCell: 0x10e165200; baseClass = UITableViewCell; frame = (0 8; 375 261.5); autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x1c0423300>>, <UISwipeActionPullView: 0x10de126a0; cellEdge = UIRectEdgeRight, actions = <NSArray: 0x1c44430c0>> )再看一下这个UISwipeActionPullView子视图,发现了我们要找的选项按钮:
(lldb) po subview2.subviews <__NSArrayM 0x1c0452ba0>( <UISwipeActionStandardButton: 0x14deae190; frame = (0 0; 591 104.5); opaque = NO; autoresize = W+H; tintColor = UIExtendedGrayColorSpace 1 1; layer = <CALayer: 0x1c0435860>>, <UISwipeActionStandardButton: 0x14debd7c0; frame = (0 0; 591 104.5); opaque = NO; autoresize = W+H; tintColor = UIExtendedGrayColorSpace 1 1; layer = <CALayer: 0x1c0621200>> )这两个button的title和action都和我们之前所创建的左滑选项相对应,所以我们可以用类似的方法遍历UITableView的子视图,拿到对应UIButton的reference进行修改。
iOS11下的层级 (用Xcode 9编译)
Xcode 9 默认使用iOS11 SDK来编译,添加打印后发现Xcode 9 编译出来的没有UITableViewWrapperView这一层,UISwipeActionPullView的子视图直接附属于UITableViewCell。
除了少了一层UITableViewWrapperView以外,其他和Xcode 8编译出来的一样。
放一下Xcode 8、9编译的对比图:
xcode8.png xcode9.png
懒人请直接看这里:p
具体实现方法 (支持iOS8-10, 11)
为了同时支持iOS8-10和iOS11, 我把操作选项外观的代码统一放在UITableView的ViewController的- (void)viewDidLayoutSubviews实现。
这样做的原因有两个:
- 原本因为iOS8-10中,左滑选项是UITableViewCell的子视图,而在iOS11中,左滑选项变成了UITableView的子视图。虽然可以用tabelCell.superview来获取tableView,不过我认为最好从高层级去操作低层级。所以统一在UITableView层处理。
- iOS8-10的UITableViewCellDeleteConfirmationView子视图出现得较晚。在代理方法willBeginEditingRowAtIndexPath中还没有出现,而在viewDidLayoutSubviews则可以保证子视图出现。
首先我们遍历UITableView的子视图拿到选项按钮(UIButton)的reference,对iOS8-10和iOS11做不同处理:
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) @property (weak, nonatomic) IBOutlet UITableView *tableView; @property (strong, nonatomic) NSIndexPath* editingIndexPath; //当前左滑cell的index,在代理方法中设置 - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; if (self.editingIndexPath) { [self configSwipeButtons]; } }Xcode 8 编译版本:(如果你使用的是Xcode 9,参见下面)
- (void)configSwipeButtons { // 获取选项按钮的reference if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { // iOS 11层级 (Xcode 8编译): UITableView -> UITableViewWrapperView -> UISwipeActionPullView for (UIView *subview in self.tableView.subviews) { if ([subview isKindOfClass:NSClassFromString(@"UITableViewWrapperView")]) { for (UIView *subsubview in subview.subviews) { if ([subsubview isKindOfClass:NSClassFromString(@"UISwipeActionPullView")] && [subsubview.subviews count] >= 2) { // 和iOS 10的按钮顺序相反 UIButton *deleteButton = subsubview.subviews[1]; UIButton *readButton = subsubview.subviews[0]; [self configDeleteButton:deleteButton]; [self configReadButton:readButton]; } } } } } else { // iOS 8-10层级: UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView NotificationCell *tableCell = [self.tableView cellForRowAtIndexPath:self.editingIndexPath]; for (UIView *subview in tableCell.subviews) { if ([subview isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")] && [subview.subviews count] >= 2) { UIButton *deleteButton = subview.subviews[0]; UIButton *readButton = subview.subviews[1]; [self configDeleteButton:deleteButton]; [self configReadButton:readButton]; [subview setBackgroundColor:[[ColorUtil instance] colorWithHexString:@"E5E8E8"]]; } } } [self configDeleteButton:deleteButton]; [self configReadButton:readButton]; }Xcode 9 编译版本:(比Xcode 8编译出来少一层)
- (void)configSwipeButtons { // 获取选项按钮的reference if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"11.0")) { // iOS 11层级 (Xcode 9编译): UITableView -> UISwipeActionPullView for (UIView *subview in self.tableView.subviews) { if ([subview isKindOfClass:NSClassFromString(@"UISwipeActionPullView")] && [subview.subviews count] >= 2) { // 和iOS 10的按钮顺序相反 UIButton *deleteButton = subsubview.subviews[1]; UIButton *readButton = subsubview.subviews[0]; [self configDeleteButton:deleteButton]; [self configReadButton:readButton]; } } } else { // iOS 8-10层级: UITableView -> UITableViewCell -> UITableViewCellDeleteConfirmationView NotificationCell *tableCell = [self.tableView cellForRowAtIndexPath:self.editingIndexPath]; for (UIView *subview in tableCell.subviews) { if ([subview isKindOfClass:NSClassFromString(@"UITableViewCellDeleteConfirmationView")] && [subview.subviews count] >= 2) { UIButton *deleteButton = subview.subviews[0]; UIButton *readButton = subview.subviews[1]; [self configDeleteButton:deleteButton]; [self configReadButton:readButton]; [subview setBackgroundColor:[[ColorUtil instance] colorWithHexString:@"E5E8E8"]]; } } } [self configDeleteButton:deleteButton]; [self configReadButton:readButton]; }注意一下这里我们用到了一个变量self.editingIndexPath,这代表着当前左滑的cell的index,方便我们获取iOS8-10上面的tableCell的reference。分别在控制进入和退出编辑模式的代理方法中设置的:
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath { self.editingIndexPath = indexPath; [self.view setNeedsLayout]; // 触发-(void)viewDidLayoutSubviews } - (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath { self.editingIndexPath = nil; }[self.view setNeedsLayout]; 这一句非常重要,它的作用强制UITableView重新绘图。只有添加了这一句,- (void)viewDidLayoutSubviews才会被调用,才能使我们的自定义外观生效。
好了,我们已经拿到了按钮(UIButton)的reference,然后就可以给按钮添加了图片,并且设置文本的字体和颜色了。
如果没有[self centerImageAndTextOnButton:readButton],则效果如下:- (void)configDeleteButton:(UIButton*)deleteButton { if (deleteButton) { [deleteButton.titleLabel setFont:[UIFont fontWithName:@"SFUIText-Regular" size:12.0]]; [deleteButton setTitleColor:[[ColorUtil instance] colorWithHexString:@"D0021B"] forState:UIControlStateNormal]; [deleteButton setImage:[UIImage imageNamed:@"Delete_icon_.png"] forState:UIControlStateNormal]; [deleteButton setBackgroundColor:[[ColorUtil instance] colorWithHexString:@"E5E8E8"]]; // 调整按钮上图片和文字的相对位置(该方法的实现在下面) [self centerImageAndTextOnButton:deleteButton]; } } - (void)configReadButton:(UIButton*)readButton { if (readButton) { [readButton.titleLabel setFont:[UIFont fontWithName:@"SFUIText-Regular" size:12.0]]; [readButton setTitleColor:[[ColorUtil instance] colorWithHexString:@"4A90E2"] forState:UIControlStateNormal]; // 根据当前状态选择不同图片 BOOL isRead = [[NotificationManager instance] read:self.editingIndexPath.row]; UIImage *readButtonImage = [UIImage imageNamed: isRead ? @"Mark_as_unread_icon_.png" : @"Mark_as_read_icon_.png"]; [readButton setImage:readButtonImage forState:UIControlStateNormal]; [readButton setBackgroundColor:[[ColorUtil instance] colorWithHexString:@"E5E8E8"]]; // 调整按钮上图片和文字的相对位置(该方法的实现在下面) [self centerImageAndTextOnButton:readButton]; } }after-layoutsubviews-1.PNG可以看到图标在左,文字在右,还互相重合。这就是我们熟悉的UIButton的外观处理,需要分别修改UILabel和UIImageView的frame:
调整过后就可以做到文章开头展示的效果了:- (void)centerImageAndTextOnButton:(UIButton*)button { // this is to center the image and text on button. // the space between the image and text CGFloat spacing = 35.0; // lower the text and push it left so it appears centered below the image CGSize imageSize = button.imageView.image.size; button.titleEdgeInsets = UIEdgeInsetsMake(0.0, - imageSize.width, - (imageSize.height + spacing), 0.0); // raise the image and push it right so it appears centered above the text CGSize titleSize = [button.titleLabel.text sizeWithAttributes:@{NSFontAttributeName: button.titleLabel.font}]; button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + spacing), 0.0, 0.0, - titleSize.width); // increase the content height to avoid clipping CGFloat edgeOffset = (titleSize.height - imageSize.height) / 2.0; button.contentEdgeInsets = UIEdgeInsetsMake(edgeOffset, 0.0, edgeOffset, 0.0); // move whole button down, apple placed the button too high in iOS 10 if (SYSTEM_VERSION_LESS_THAN(@"11.0")) { CGRect btnFrame = button.frame; btnFrame.origin.y = 18; button.frame = btnFrame; } }swipe-customize-2.PNGPS:假如仅支持iOS8-10的话,我个人是倾向于创建一个custom class,继承UITableViewCell,然后在该custom class中-(void)layoutSubviews来实现的。那样代码更干净,不需要特意去调用[self.view setNeedsLayout]; 不过为了支持新版本总是要有所牺牲的。
3. TableCell上有其它按钮的处理方法
我自己做的时候遇到了一种特殊情况,UITableViewCell上面带有比较显著的button,类似下图的这种情况:swipe-button-1.PNG这种情况比较尴尬的就是当你左滑的时候如果刚好碰到了YES或者NO button, 在进入左滑选项的同时会触发按钮选项,相当容易引发误操作。为了解决这个问题,我在TableViewController中实现了下面两个代理方法:
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *tableCell = [tableView cellForRowAtIndexPath:indexPath]; // disable button touch event during swipe for (UIView *view in [tableCell.contentView subviews]) { if ([view isKindOfClass:[UIButton class]]) { [view setUserInteractionEnabled:NO]; } } } - (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *tableCell = [tableView cellForRowAtIndexPath:indexPath]; for (UIView *view in [tableCell.contentView subviews]) { if ([view isKindOfClass:[UIButton class]]) { [view setUserInteractionEnabled:YES]; } } }tableView:willBeginEditingRowAtIndexPath是在cell进入editing mode之前调用的,在这里将contentView下面的所有按钮的交互设置为disabled。
tableView:didEndEditingRowAtIndexPath是在cell即将退出editing mode时调用的,在这里将之前被disable的所有button的交互重新设置为enabled。这样就可以保证在左滑菜单出现的时候,原本cell上的那些按钮都处于不能点按的状态,也就不会触发误操作了。
PS: 试过直接disable 整个contentView不起作用,必须直接disable对应的UIButton才行,推测跟apple自己处理event的有限次序有关。
<最后更新时间:2017-09-11>
链接:http://www.jianshu.com/p/779f36c21632
相关推荐
ios UITableView 自定义右滑删除的实现代码
公司有个奇葩需求。删除按钮带点圆角 不止如此,还有cell之间有间隔,cell圆角,cell左右有间隔。如下图!!!!! 内心奔溃的我想了想了很多方法。(获取系统自带按钮改圆角也试过,自定义手势也试过)最后决定全部自定义。个人感觉这样最合适。下面是效果图 今天有时间,稍微说下实现方式: 这个项目工程只是提供一种思路,应对场景是 需要自定义左滑删除按钮的样式。 因为项目本身并不是修改系统的左滑删除,而是自定义实现,所以任何样式都算使用。 下面先说下项目的结构类型 最底下自然是uitableviewCell 然后放入一个scrollview 填满整个cell (若想有左右间隔,也可以不填满)
ios11下tableView自定义侧滑删除图片
ios11下tableView自定义侧滑删除图片 2018年05月24日 18:19:14 新手小小鸟 阅读数:951 之前写ios11下tableView适配过程中遗留了一个问题,随后找到的了解决方法,一直忘了更新,具体的问题是在ios11下,自定义侧滑删除图片时,图片莫名其妙的被渲染成了白色,不管什么颜色的图片都会变成一样的白色,为此苦恼了很久,不清楚现在苹果是否修复了这个问题,在此记录一...
iOS开发之UITableView左滑删除等自定义功能
今天来给大家介绍下iOS开发中UITableView左滑实现微信中置顶,删除等功能。对大家开发iOS具有一定的参考借鉴价值,有需要的朋友们一起来看看吧。
iOS改变cell的侧滑显示图片
该想法只是为了赶工期,并且只能对一个按钮有效果。切记切记。有些时候要在侧滑的时候显示图片代替文字显示从简处理流程 1:在使用的cell里申明一个view一定强引用类型 2:在cell初始化的函数里加载view 3:重写commitEditingStyle进行func *4:在titleForDeleteConfirmationButtonForRowAtIndexPath设置宽度 看效果图 对比一下...
iOS11解决UITableView侧滑删除无限拉伸的方法
主要给大家介绍了关于iOS11如何解决UITableView侧滑删除无限拉伸的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
一文说清Arduino如何实现舵机平滑转动(机器人场景)
深入讲解如何利用arduino控制舵机转动,实现机器人场景中的平稳运动。通过代码优化与脉冲宽度调节,让舵机动作更精准流畅,适用于各类自动化项目。
iOS tableViewCell 自定义左滑删除按钮样式添加图片
ios12 下显示图片 ios8到10 - (void)viewDidLayoutSubviews{ [super viewDidLayoutSubviews]; [self configSwipeButtons]; } -(void)tableView:(UITableView*)tableView willBeginEditingRowAtIn...
【编译原理】LL(1)分析方法 生成语法树(c++实现)
基本流程 输入文法->消除左递归->提取左公共因子->求FIRST集->求FOLLOW集->LL(1)分析表->表驱动的预测语法分析过程->输出语法分析结果和语法树
ios 开发设置左滑退出_iOS 自定义左滑/侧滑删除,适配 iOS13 以上版本
众所周知,在 iOS 里 UITableView 的左滑/侧滑删除的功能还是挺美观的,最近项目的需求里就用到了这个样式需求图片当时接到这个需求的时候也在网上查找了很多资料,非常感谢这篇文章带给我的灵感iOS cell自定义左滑/侧滑删除(支持iOS11)但iOS13 以上的系统左滑控件的层级以及类名都发生了变化,以前的方法明显不够用了,通过不断的断点分析,类名输出后终于正确的适配上了 iOS13,...
ddr3ip核心_DDR3 IP 核配置
DDR3 控制器 IP 核2.DDR3 IP核配置点击 Flow Navigator 面板下的“Project Manager -->IP Catalog”。 在“Memories & Storage Elements -->Memory Interface Generators”分类展开后,可以看到名为“Memory Interface Generator (MIG 7 ...
Apple 网页 SRP 登录系列文章(四):Hashcash 工作量证明与完整登录流程
本文是Apple SRP登录系列文章的收官之作,重点解析了Apple独有的Hashcash工作量证明机制并展示了完整的登录流程实现。文章详细介绍了Hashcash的安全目的、格式标准、计算核心算法及难度评估方法,特别提供了Python实现代码。同时还讲解了如何动态获取服务器Hashcash参数以及建立容错机制。最后呈现了完整的Apple SRP登录主函数架构,为开发者提供了从理论到实践的全面指导。全文通过代码示例和流程分析,系统性地阐述了Apple安全登录机制的技术细节。
iOS11 tableview左滑到底禁用删除
iOS11 tableview左滑到底禁用删除
现代密码学5.3--Hash and MAC
现代密码学5.3--Hash and MAC 博主正在学习INTRODUCTION TO MODERN CRYPTOGRAPHY (Second Edition) --Jonathan Katz, Yehuda Lindell,做一些笔记供自己回忆,如有错误请指正。整理成一个系列现代密码学,方便检索。 第二章定义了完美安全及其对应的密码方案“一次一密”, 第三章介绍了多种安全定义 3.1-3.3 计算安全,PRG和基于PRG构造的满足计算安全的密码方案; 3.4-3.5 CPA安全,PRF和基于PRF构
自定义UITableView实现自定义左滑删除按钮及多按钮,拖拽cell和表头进行排序
本文介绍了能拖拽cell和表头进行排序的自定义UITableView,并且能自定义左滑显示的UIButton样式。 github传送门 先看左滑自定义按钮效果图 : override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableVi...
web渗透学习手册
依据多年的渗透测试项目经验及个人理解,对漏洞分类
2万字长文:海豚调度器(DolphinScheduler)面试题深入了解
DAG图(有向无环图)是海豚调度器中表示工作流任务依赖关系的一种方式。在DolphinScheduler中,每个任务是一个节点,任务之间的依赖关系通过有向边连接这些节点来表示。无环:保证了工作流的执行顺序是确定的,避免了无限循环的问题。有向:箭头指示了任务的执行方向,即上一个任务的输出可以作为下一个任务的输入。依赖表示:通过图形化界面,用户可以通过拖拽连接线来定义任务之间的先后顺序和依赖关系。并行处理:DAG图可以表示出任务的并行关系,允许多个任务在没有直接依赖关系的情况下同时执行。条件分支。
UITableView自定义左划删除遇到的问题
2019独角兽企业重金招聘Python工程师标准>>> ...
一套适合 ABAP 初级和中级开发人员,从入门到提高的 ABAP 学习教程
曾几何时,ABAP 就是 SAP 的代名词。ABAP 这门编程语言造就了 SAP 名噪一时的 R/3 产品,同时也是如今 SAP 旗舰级产品,SAP S/4HANA 底层的实现语言。 ABAP 不仅代表着 SAP 这家公司在企业级管理软件市场辉煌的过去,ABAP 自身也在不断地进化着。SAP 不仅在本地部署(On-Premise)领域继续保持着自己绝对的统治地位,而且在云应用领域(Software-as-a-Service, 简称 SaaS), 也推出了自己的解决方案,比如 SAP S/4HANA Clo
【Swift】UIKit:UISegmentedControl、UISlider、UIStepper、UITableView和UICollectionView
摘要:本文介绍了iOS开发中两个常用UI组件:UISegmentedControl分段选择器和UISlider滑块组件。UISegmentedControl用于单选项分段选择,支持文字/图片选项、自定义颜色和默认选中项,通过valueChanged事件响应选择变化。UISlider用于连续数值调节,可设置数值范围、步长和外观样式,支持实时或滑动结束回调。文章详细说明了两个组件的核心功能、关键属性方法,并提供了Swift代码示例,分别演示了分段选择器的创建使用和滑块控制图片透明度的实现。
pscad IEEE标准系统搭建说明
pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。
jdk-8u144-linux-x64.tar.gz.
该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包
iOS tableView侧滑多按钮的处理
为什么80%的码农都做不了架构师?>>> ...
jre9下载 jdk9
(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】
IOS 表视图(UITableVIew)的使用方法(8)表视图的编辑功能(多选)
在表视图的删除操作中,每次只能够对其中一个单元进行删除,如果想要同时删除多条记录,不得不挨个地进行标准的删除操作 所以如果能够实现多选的机制,无论是删除还是其他功能的嫁接,都会变得更加方便 当UITableView进入编辑模式时,默认会将所有的单元行向右缩进。不过缩进后多出的空间是否显示系统图标以及显示哪种图标却是由开发者通过代理回调函数自己来定义。这样的话,如果我们不让它显示任何东西,而是用...
复分析 阿尔福斯(Ahlfors) 第三版答案 英文
答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案
iOS图片异步加载与缓存优化:FAImageView核心功能与实战指南
在iOS应用开发中,图片异步加载与缓存是提升用户体验和性能的关键技术。其核心原理是通过后台线程处理网络请求,避免阻塞主线程,并结合多级缓存机制(内存与磁盘)减少重复下载与流量消耗。这项技术的价值在于显著改善列表滑动流畅度、降低内存峰值并优化网络资源使用。典型的应用场景包括社交媒体的动态流、电商平台的商品列表以及新闻资讯的内容展示。针对这些需求,FAImageView等开源库提供了经过优化的解决方案,通过简洁的API封装了复杂的线程管理与缓存策略,帮助开发者快速集成高效的图片加载功能,并支持与SwiftUI的
iOS 总结1
1:让tableview 执行这个方法,1秒中之后,取消选中,执行这个方法,传进去indexpath的参数,去执行取消,1秒之后标志也小时。在select 中执行deselect方法, 选中标记,不选中不标记。 2。UITableViewController 两个属性:(1)tableview 设置这个属性,访问和设置表视图(2)clearsSelectionOnV...
1089



被折叠的 条评论
为什么被折叠?



