精华内容
下载资源
问答
  • UITableViewCell

    2018-06-01 00:36:00
    译-UITableViewCell中嵌套 · 快乐的鲸鱼 UITableViewCell中设置动态大小的圆形imageview - yoyoso的个人页面 如何让 UITableViewCell 中的 imageView 大小固定 _ 里脊串的开发随笔 iOS UITableViewCell 中 调整...

    译-UITableViewCell中嵌套 · 快乐的鲸鱼


    UITableViewCell中设置动态大小的圆形imageview - yoyoso的个人页面

    如何让 UITableViewCell 中的 imageView 大小固定 _ 里脊串的开发随笔

    iOS UITableViewCell 中 调整imageView 的图片大小 - kingBo0259 - 博客园


    优化UITableViewCell高度计算的那些事 · sunnyxx的技术博客

    iOS 使用Autolayout实现UITableView的Cell动态布局和高度动态改变 - CSDN博客

    ios - Using Auto Layout in UITableView for dynamic cell layouts & variable row heights - Stack Overflow

    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.tableView.rowHeight = UITableViewAutomaticDimension;
    }
    
    -(CGFloat)tableView:(UITableView *)tableView
    estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return 100*indexPath.row;
    }
    

    657299-20180610200119759-307306295.png

    label.lines=0(允许多行显示);

    line break(以何种方式换行);

    657299-20180610200801637-2096486960.png

    657299-20180610225830373-1659815983.png


    如何在UITableViewCell的中添加向右箭头和箭头前的文本 - CSDN博客


    iOS-OC-设置UITableViewCell之间的间距(推荐第四种) - CSDN博客


    iOS UITableView中cell的自带样式 - 简书

    UITableviewCell子类修改默认的样式

    - (instancetype)initWithStyle:(UITableViewCellStyle)style
                  reuseIdentifier:(NSString *)reuseIdentifier
    {
        self=[super initWithStyle:UITableViewCellStyleValue1
                  reuseIdentifier:reuseIdentifier];
        if (self)
        {
        //code
        }
        return self;
    }
    

    iOS中自定义输入文本框的cell(UITextFieldCell)的使用技巧 - CSDN博客

    转载于:https://www.cnblogs.com/louyizhidu/p/9119829.html

    展开全文
  • UITableviewcell

    2014-12-10 23:17:50
    一、UITableviewcell的一些介绍 UITableView的每一行都是一个UITableViewCell,通过dataSource的 tableView:cellForRowAtIndexPath:方法来初始化每⼀行 UITableViewCell内部有个默认的子视图:contentView,...

    一、UITableviewcell的一些介绍

    UITableView的每一行都是一个UITableViewCell,通过dataSource的 tableView:cellForRowAtIndexPath:方法来初始化每⼀行

    UITableViewCell内部有个默认的子视图:contentView,contentView是UITableViewCell所显示内容的父视图,可显示一些辅助指示视图

    辅助指示视图的作⽤是显示一个表示动作的图标,可以通过设置UITableViewCell的 accessoryType来显示,默认是UITableViewCellAccessoryNone(不显⽰示辅助指⽰示视图), 其他值如下:

    UITableViewCellAccessoryDisclosureIndicator

    UITableViewCellAccessoryDetailDisclosureButton

    UITableViewCellAccessoryCheckmark

    还可以通过cell的accessoryView属性来自定义辅助指示视图(⽐如往右边放一个开关) 

     

    二、问题

      cell的工作:在程序执行的时候,能看到多少条,它就创建多少条数据,如果视图滚动那么再创建新显示的内容。(系统自动调用)。即当一个cell出现在视野范围内的时候,就会调用创建一个cell。这样的逻辑看上去没有什么问题,但是真的没有任何问题吗?

      当创建调用的时候,我们使用nslog打印消息,并打印创建的cell的地址。我们发现如果数据量非常大,用户在短时间内来回滚动的话,那么会创建大量的cell,一直开辟空间,且如果是往回滚,通过打印地址,我们会发现它并没有重用之前已经创建的cell,而是重新创建,开辟新的存储空间。

      那有没有什么好的解决办法呢?

     

    三、cell的重用原理

    (1) iOS设备的内存有限,如果用UITableView显示成千上万条数据,就需要成千上万 个UITableViewCell对象的话,那将会耗尽iOS设备的内存。要解决该问题,需要重用UITableViewCell对象

    (2)重⽤原理:当滚动列表时,部分UITableViewCell会移出窗口,UITableView会将窗口外的UITableViewCell放入一个对象池中,等待重用。当UITableView要求dataSource返回 UITableViewCell时,dataSource会先查看这个对象池,如果池中有未使用的 UITableViewCell,dataSource则会用新的数据来配置这个UITableViewCell,然后返回给 UITableView,重新显示到窗口中,从而避免创建新对象 。这样可以让创建的cell的数量维持在很低的水平,如果一个窗口中只能显示5个cell,那么cell重用之后,只需要创建6个cell就够了。

    (3)注意点:还有⼀个非常重要的问题:有时候需要自定义UITableViewCell(用⼀个子类继 承UITableViewCell),而且每⼀行⽤的不一定是同一种UITableViewCell,所以一 个UITableView可能拥有不同类型的UITableViewCell,对象池中也会有很多不同类型的 UITableViewCell,那么UITableView在重⽤用UITableViewCell时可能会得到错误类型的 UITableViewCell

    解决⽅方案:UITableViewCell有个NSString *reuseIdentifier属性,可以在初始化UITableViewCell的时候传入一个特定的字符串标识来设置reuseIdentifier(一般用UITableViewCell的类名)。当UITableView要求dataSource返回UITableViewCell时,先 通过一个字符串标识到对象池中查找对应类型的UITableViewCell对象,如果有,就重用,如果没有,就传入这个字符串标识来初始化⼀一个UITableViewCell对象。

    图片示例:

     

    说明:一个窗口放得下(可视)三个cell,整个程序只需要创建4个该类型的cell即可。

     

    四、cell的优化代码

     代码示例:

    复制代码
     1 #import "NJViewController.h"
     2 #import "NJHero.h"
     3 
     4 // #define ID @"ABC"
     5 
     6 @interface NJViewController ()<UITableViewDataSource, UITableViewDelegate>
     7 /**
     8  *  保存所有的英雄数据
     9  */
    10 @property (nonatomic, strong) NSArray *heros;
    11 @property (weak, nonatomic) IBOutlet UITableView *tableView;
    12 
    13 @end
    14 
    15 @implementation NJViewController
    16 
    17 #pragma mark - 懒加载
    18 - (NSArray *)heros
    19 {
    20     if (_heros == nil) {
    21         // 1.获得全路径
    22         NSString *fullPath =  [[NSBundle mainBundle] pathForResource:@"heros" ofType:@"plist"];
    23         // 2.更具全路径加载数据
    24         NSArray *dictArray = [NSArray arrayWithContentsOfFile:fullPath];
    25         // 3.字典转模型
    26         NSMutableArray *models = [NSMutableArray arrayWithCapacity:dictArray.count];
    27         for (NSDictionary *dict in dictArray) {
    28             NJHero *hero = [NJHero heroWithDict:dict];
    29             [models addObject:hero];
    30         }
    31         // 4.赋值数据
    32         _heros = [models copy];
    33     }
    34     // 4.返回数据
    35     return _heros;
    36 }
    37 
    38 - (void)viewDidLoad
    39 {
    40     [super viewDidLoad];
    41     // 设置Cell的高度
    42     // 当每一行的cell高度一致的时候使用属性设置cell的高度
    43     self.tableView.rowHeight = 160;
    44 }
    45 
    46 #pragma mark - UITableViewDataSource
    47 // 返回多少组
    48 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    49 {
    50     return 1;
    51 }
    52 // 返回每一组有多少行
    53 - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    54 {
    55     return self.heros.count;
    56 }
    57 // 当一个cell出现视野范围内的时候就会调用
    58 // 返回哪一组的哪一行显示什么内容
    59 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    60 {
    61     // 定义变量保存重用标记的值
    62     static NSString *identifier = @"hero";
    63     
    64 //    1.先去缓存池中查找是否有满足条件的Cell
    65     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    66 //    2.如果缓存池中没有符合条件的cell,就自己创建一个Cell
    67     if (cell == nil) {
    68         //    3.创建Cell, 并且设置一个唯一的标记
    69         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
    70         NSLog(@"创建一个新的Cell");
    71     }
    72 //    4.给cell设置数据
    73     NJHero *hero = self.heros[indexPath.row];
    74     cell.textLabel.text = hero.name;
    75     cell.detailTextLabel.text = hero.intro;
    76     cell.imageView.image = [UIImage imageNamed:hero.icon];
    77     
    78    //  NSLog(@"%@ - %d - %p", hero.name, indexPath.row, cell);
    79     
    80     // 3.返回cell
    81     return cell;
    82 }
    83 
    84 #pragma mark - 控制状态栏是否显示
    85 /**
    86  *   返回YES代表隐藏状态栏, NO相反
    87  */
    88 - (BOOL)prefersStatusBarHidden
    89 {
    90     return YES;
    91 }
    92 @end
    复制代码

    缓存优化的思路:

    (1)先去缓存池中查找是否有满足条件的cell,若有那就直接拿来

    (2)若没有,就自己创建一个cell

    (3)创建cell,并且设置一个唯一的标记(把属于“”的给盖个章)

    (4)给cell设置数据

    注意点:

    定义变量用来保存重用标记的值,这里不推荐使用宏(#define来处理),因为该变量只在这个作用域的内部使用,且如果使用宏定义的话,定义和使用位置太分散,不利于阅读程序。由于其值不变,没有必要每次都开辟一次,所以用static定义为一个静态变量。

    展开全文
  • uitableviewcell

    2014-09-25 10:58:18
    -(uitableviewcell *)tableview:(uitableview *)tableview cellforrowindexpath:(nsindexpath)indexpath 然后再这个方法里面创建cell 创建一个cell的一个可以重复使用的模板,...

    使用UITableViewController


    //初始化UITAbleviewcontroller 并且分配空间,初始化UItableviewcontroller 的风格

    UITableViewController *tableViewController=[[ UITableViewController alloc]initWitchStyle:UITableViewCellStyleDefault];


    创建一个导航控制器,并且把导航控制器的rootviewcontroller

    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:tableViewController];


    讲讲tableview, tableview主要有两个方面,一个是显示(uitableviewdatasource),一个是动作(uitableviewdelegate)

    tableview的组成

    了解了组成,就知道怎么设置属性,需要设置的地方就知道了

    section的数目 ----用到uitableviewdatasource的方法 -(NSInteger)numberofsectionintableview:(uitableview)uitableview

    row的数目 ----用到了uitableviewdatasource的方法-(nsinteger)tableview:(uitableview)tableview numberofrowinsection:(nsinteger)section

    table header

    section header

    table cell

    section footer



    显示cell

    -(uitableviewcell *)tableview:(uitableview *)tableview cellforrowindexpath:(nsindexpath)indexpath


    然后再这个方法里面创建cell

    创建一个cell的一个可以重复使用的模板,dequeuereusablecellwithidentifier:  indexPath    这个方法试用与IOS 6  哪里好呢,不知道 ,呵呵

    UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];

    if(!cell){

    cell= [ uitableviewcell alloc]initwithstyle: xxx reuseidentifier:@"MyIdentifier"

    }

    cell.textlabel.text = xxx

    cell.detailtextlabel.text = xxx


    设置一下cell的属性 OK



    然后呢你想点击一下CELL的时候,切换到下一个页面,  或者点击cell的accessory的时候切换页面,就需要用到uitableviewdalegate的方法了


    -(void) tableview:(uitableview *)tableview didselecrowatindexpath:(nsindexpath)indexpath


    nsinteger row = indexpath.row                           //获取行号

    idobjtodispaly =[myobjects objctatindex:row]  //把行的内容传给下一个view  根据这个内容作出不同的选择


    myviewcontroller *myviewcontroller = 初始化;


    通过导航,把视图切换过去

    [self.navigationcontrollerpushviewcontroller:myviewcontroller animated:YES];



    手工,视图切换过去了,那



    展开全文
  • 文章目录I、问题分析II、使用方法交换,全局修改see also ... I、问题分析 ...这种方式添加的,通过试图分析发现被系统自带的UITableViewCellContentView遮挡在底部了,所以需要改规范的做法 cell.con

    前言

    今天升级最新IDE Xcode,准备适配iOS14 API,结果发现app首页的cell中按钮也无法点击了。

    I、问题分析

    iOS14 UITableViewCell的子试图不能点击或者滑动等手势响应问题,发现有问题的cell基本都是直接

    cell.addSubView(tempView1)
    
    

    这种方式添加的,通过Xcode自带的DebugViewHierarchy视图分析发现问题的原因是:被系统自带的UITableViewCellContentView遮挡在底部了

    在这里插入图片描述

    在这里插入图片描述

    所以需要改规范的做法

    cell.contentView.addSubView(tempView1)
    
    

    温馨提示:如果你用旧版的Xcode打包,而非使用Xcode12以上版本编译打包的话,是不会有问题。一旦你使用了Xcode12打包,就会出现此问题。(但是苹果迟早会限制高于Xcode12才可以上传appstore,所以一旦使用了不规范的代码,早晚都要面临这个问题

    1.0 其他分析视图层级的方法:私有API _printHierarchy 和recursiveDescription

    关于视图层级分析你也可以使用私有API _printHierarchyrecursiveDescription 在lldb 窗口进行分析:

    例如先打印VC层级(lldb) po [[[UIWindow keyWindow] rootViewController] _printHierarchy]

    再使用目标View的地址进行recursiveDescription打印子视图的层级。

    • po [0x10ff5e5e0 recursiveDescription]
    (lldb) po [0x10ff5e5e0 recursiveDescription]
    <UITableViewCell: 0x10ff5e5e0; frame = (0 767.5; 375 120); hidden = YES; autoresize = W; layer = <CAGradientLayer: 0x280b80860>>
       | <_UISystemBackgroundView: 0x10fe2d170; frame = (0 0; 375 120); layer = <CAGradientLayer: 0x280c58500>; configuration = <UIBackgroundConfiguration: 0x283aa54a0; Base Style = List Grouped Cell; backgroundColor = <UIDynamicSystemColor: 0x2818d3140; name = tableCellGroupedBackgroundColor>>>
       |    | <UIView: 0x10fe2d310; frame = (0 0; 375 120); clipsToBounds = YES; layer = <CAGradientLayer: 0x280c58640>>
       | <UIView: 0x10ff9a820; frame = (0 0; 375 120); layer = <CAGradientLayer: 0x280b9db60>>
       |    | <UIButton: 0x10ff9ab10; frame = (17 0; 170.5 60); opaque = NO; layer = <CAGradientLayer: 0x280b9dc40>>
       |    |    | <UIImageView: 0x10fe70710; frame = (0 16; 28 28); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280be9520>>
       |    |    | <UIButtonLabel: 0x10ff9af70; frame = (38 21.5; 86 17); text = '商户交易汇总'; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b9dc80>>
       |    | <UIButton: 0x10ff9bd40; frame = (187.5 0; 170.5 60); opaque = NO; tag = 1; layer = <CAGradientLayer: 0x280b9e1c0>>
       |    |    | <UIImageView: 0x10ffacfd0; frame = (0 16; 28 28); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b93220>>
       |    |    | <UIButtonLabel: 0x10ff9c1a0; frame = (38 21.5; 100 17); text = '代理商交易汇总'; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b9e340>>
       |    | <UIButton: 0x10ff9cda0; frame = (17 60; 170.5 60); opaque = NO; tag = 2; layer = <CAGradientLayer: 0x280b9e540>>
       |    |    | <UIImageView: 0x10ffab1f0; frame = (0 16; 28 28); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b92f40>>
       |    |    | <UIButtonLabel: 0x10ff9d200; frame = (38 21.5; 86 17); text = '终端激活汇总'; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b9e680>>
       |    | <UIButton: 0x10ff9db20; frame = (187.5 60; 170.5 60); opaque = NO; tag = 3; layer = <CAGradientLayer: 0x280b9ea20>>
       |    |    | <UIImageView: 0x10ffa95d0; frame = (0 16; 28 28); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b92ce0>>
       |    |    | <UIButtonLabel: 0x10ff9df80; frame = (38 21.5; 86 17); text = '商户终端汇总'; opaque = NO; userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b9eb80>>
       |    | <UIView: 0x10ff9e8a0; frame = (15 60; 345 0.5); layer = <CAGradientLayer: 0x280b9ef00>>
       |    | <UIView: 0x10ff9ea10; frame = (15 120; 345 0.5); layer = <CAGradientLayer: 0x280b9f0c0>>
       | <UITableViewCellContentView: 0x10ffaafa0; frame = (0 0; 375 120); gestureRecognizers = <NSArray: 0x281fc73c0>; layer = <CAGradientLayer: 0x280b808e0>>
       |    | <UIImageView: 0x110f07d00; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CAGradientLayer: 0x280b7e220>>
    
    
    
    

    1.1 注意事项

    因为此问题涉及的是添加子视图cell.addSubView,因此与之对应的方法(UITableViewCell *)[SubView superview]cell.subviews 都要注意谨慎使用和处理

    II、使用方法交换,全局修改

    如果错误代码比较多,可以采用hook,进行便捷的方法进行修改。

    例如125个文件的1452个地方使用错误的方法,这个如果不使用hook高质工作量有点大在这里插入图片描述
    所以通过Runtime hook cell的addSubView 方法强制修改为正确的添加cell 子视图的方式

    2.1 全局修改

    • 只允许添加 UITableViewCellContentView,其余都直接添加到self.contentView
    //
    //  UITableViewCell+CRMaddSubView.m
    //  Housekeeper
    //
    //  Created by mac on 2020/9/18.
    //  Copyright © 2020 QCT. All rights reserved.
    //
    
    #import "UITableViewCell+CRMaddSubView.h"
    
    @implementation UITableViewCell (CRMaddSubView)
    + (void)load {
        // Swizzle addSubView
        [UITableViewCell sensorsdata_swizzleMethod:@selector(addSubview:) withMethod:@selector(kunnan_addSubview:)];
        
    }
    
    - (void)kunnan_addSubview:(UIView *)view {
    
        
        
        if  ([view isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]) {//允许 addSubView UITableViewCellContentView 
            
            [self kunnan_addSubview:view];//实现方法,因为已经进行了 swizzle,相当于调用原来的方法
            
    
            
        } else {
            
            [self.contentView addSubview:view];
            
        }
    
    
    
    }
    
    
    
    @end
    
    

    2.2 注意事项

    因为此问题涉及的是添加子视图cell.addSubView,因此与之对应的方法(UITableViewCell *)[SubView superview] 和cell.subviews 都要注意谨慎使用和处理

    具体例子如下2.2.1 和2.2.2

    2.2.1 cell.subviews

    因为这是针对全局的,所以测试的覆盖面也要广。 比如获取子视图采用cell.subviews 也要记得修改为 cell.contentView.subviews.

        UIButton * btn = cell.contentView.subviews[2-1];
    
    

    2.2.2 通过superview 获取cell的也需做相关修改

    • 经过全局hook之后,以下的代码就是错误的
      (UITableViewCell *)[textField superview]

    • 全局搜索进行修改
      在这里插入图片描述

            UITableViewCell * myCell = (UITableViewCell *)[textField superview].superview;
    
    

    所以使用class的时候,最好写得健壮性强点,进行类型判断,避免一旦类型错误,就会找不到对应的方法,发送闪退

        UIView * textFieldsuperview = [textField superview];
        UITableViewCell * myCell = nil;
        
        if([textFieldsuperview isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]){
            
            
            
             myCell= (UITableViewCell *)[textFieldsuperview superview];
    
        }else{
            
            return;
            
            
        }
        
    
    

    能遇见这样的奇葩代码,只能说之前的同事很”牛逼啊。。。。“

    2.3 使用到的工具类

    • h
    //
    //  NSObject+CRMSwizzling.h
    //  Housekeeper
    //
    //  Created by mac on 2020/9/18.
    //  Copyright © 2020 QCT. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    typedef IMP *IMPPointer;
    /**
     让所有继承自NSObject的子类,都具有Method Swizzling的能力。
     */
    
    @interface NSObject (CRMSwizzling)
    
    
    /**
    交换方法名为 originalSEL 和方法名为 alternateSEL 两个方法的实现
    @param originalSEL 原始方法名
    @param alternateSEL 要交换的方法名称
    */
    + (BOOL)sensorsdata_swizzleMethod:(SEL)originalSEL withMethod:(SEL)alternateSEL;
    
    
    
    
    /**
     方式二
     */
    + (BOOL)swizzle:(SEL)original with:(IMP)replacement store:(out IMPPointer)store;
    
    
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    
    • m
    //
    //  NSObject+CRMSwizzling.m
    //  Housekeeper
    //
    //  Created by mac on 2020/9/18.
    //  Copyright © 2020 QCT. All rights reserved.
    //
    
    #import <objc/runtime.h>
    #import <objc/message.h>
    
    
    #import "NSObject+CRMSwizzling.h"
    
    BOOL class_swizzleMethodAndStore(Class class, SEL original, IMP replacement, IMPPointer store);
    
    BOOL class_swizzleMethodAndStore(Class class, SEL original, IMP replacement, IMPPointer store) {
        
        IMP imp = NULL;
        Method method = class_getInstanceMethod(class, original);
        
        if (method) {
            
            const char *type = method_getTypeEncoding(method);
            imp = class_replaceMethod(class, original, replacement, type);
            
            
            if (!imp) {
                
                imp = method_getImplementation(method);
                
            }
        }
        if (imp && store) {
            *store = imp;
        }
        return (imp != NULL);
    }
    
    
    
        
    @implementation NSObject (CRMSwizzling)
    
    + (BOOL)sensorsdata_swizzleMethod:(SEL)originalSEL withMethod:(SEL)alternateSEL {
        // 获取原始方法
        Method originalMethod = class_getInstanceMethod(self, originalSEL);
        // 当原始方法不存在时,返回 NO,表示 Swizzling 失败
        if (!originalMethod) {
            return NO;
        }
    
        // 获取要交换的方法
        Method alternateMethod = class_getInstanceMethod(self, alternateSEL);
        // 当要交换的方法不存在时,返回 NO,表示 Swizzling 失败
        if (!alternateMethod) {
            return NO;
        }
    
        // 获取 originalSEL 方法的实现
        IMP originalIMP = method_getImplementation(originalMethod);
        // 获取 originalSEL 方法的类型
        const char * originalMethodType = method_getTypeEncoding(originalMethod);
        // 往类中添加 originalSEL 方法,如果已经存在会添加失败,并返回 NO
        if (class_addMethod(self, originalSEL, originalIMP, originalMethodType)) {
            // 如果添加成功了,重新获取 originalSEL 实例方法
            originalMethod = class_getInstanceMethod(self, originalSEL);
        }
    
        // 获取 alternateIMP 方法的实现
        IMP alternateIMP = method_getImplementation(alternateMethod);
        // 获取 alternateIMP 方法的类型
        const char * alternateMethodType = method_getTypeEncoding(alternateMethod);
        // 往类中添加 alternateIMP 方法,如果已经存在会添加失败,并返回 NO
        if (class_addMethod(self, alternateSEL, alternateIMP, alternateMethodType)) {
            // 如果添加成功了,重新获取 alternateIMP 实例方法
            alternateMethod = class_getInstanceMethod(self, alternateSEL);
        }
    
        // 交换两个方法的实现
        method_exchangeImplementations(originalMethod, alternateMethod);
    
        // 返回 YES,表示 Swizzling 成功
        return YES;
    }
    
    
    
    + (BOOL)swizzle:(SEL)original with:(IMP)replacement store:(out IMPPointer)store {
        return class_swizzleMethodAndStore(self, original, replacement, store);
    }
    
    
    
    @end
    
    

    see also

    extension UITableViewCell {
        
        class func ios14Bug() {
            
            let sel1 = #selector(UITableViewCell.runtime_addSubview(_:))
            let sel2 = #selector(UITableViewCell.addSubview(_:))
            
            let method1 = class_getInstanceMethod(UITableViewCell.self, sel1)!
            let method2 = class_getInstanceMethod(UITableViewCell.self, sel2)!
            
            let isDid: Bool = class_addMethod(self, sel2, method_getImplementation(method1), method_getTypeEncoding(method1))
            if isDid {
                class_replaceMethod(self, sel1, method_getImplementation(method2), method_getTypeEncoding(method2))
            } else {
                method_exchangeImplementations(method2, method1)
            }
        }
        
        @objc func runtime_addSubview(_ view: UIView) {
            // 判断不让 UITableViewCellContentView addSubView自己
            if view.isKind(of: NSClassFromString("UITableViewCellContentView")!) {
                runtime_addSubview(view)
            } else {
                self.contentView.addSubview(view)
            }
        }
    }
    
    
    
    

    还发现他的另一个不规范使用cell API导致的问题,具体请看这里

    展开全文
  • 利用原始UITableViewcell强大的自适应性能,改造UITableViewcell,与自定义UITableViewcell略有不同
  • Custom UITableViewCell

    2020-12-31 20:47:57
    <div><p>Potentionaly ... Does this work with custom UITableViewCell? If so, can you please give me any hint. I cannot get it working. Thanks!</p><p>该提问来源于开源项目:3lvis/DATASource</p></div>
  • 自定义UITableViewCell

    2016-10-18 16:17:24
    自定义UITableViewCell
  • UITableViewCell定制

    2016-09-10 13:53:27
    UITableViewCell定制
  • UITableViewCell详解

    千次阅读 2017-10-20 12:33:48
    UITableViewCell详解 UITableViewCell类定义了在UITableView对象中出现的cell的属性和方法。一个的UITableViewCell对象包含了控制一个cell在选中、高亮、编辑、控制等状态下的属性和方法。该类还包括用于设置和管理...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,532
精华内容 3,012
关键字:

uitableviewcell