【问题标题】:Set custom font for UITableView swipe action (UIContextualAction)为 UITableView 滑动操作设置自定义字体(UIContextualAction)
【发布时间】:2019-06-13 21:20:43
【问题描述】:

UIContextualAction中的标题如何设置自定义字体?

我试过UIAppearance,但没有任何运气......

干杯! :)

【问题讨论】:

    标签: ios uitableview uitableviewrowaction uicontextualaction uiswipeactionsconfiguration


    【解决方案1】:

    我找到了一种方法来使用图像属性而不是标题...

    标准字体(删除/重命名)

    自定义字体(删除/重命名)

    要创建标签的图像,我有这个扩展:

    extension UIImage {
    
        /// This method creates an image of a view
        convenience init?(view: UIView) {
    
            // Based on https://stackoverflow.com/a/41288197/1118398
            let renderer = UIGraphicsImageRenderer(bounds: view.bounds)
            let image = renderer.image { rendererContext in
                view.layer.render(in: rendererContext.cgContext)
            }
    
            if let cgImage = image.cgImage {
                self.init(cgImage: cgImage, scale: UIScreen.main.scale, orientation: .up)
            } else {
                return nil
            }
        }
    }
    

    然后我有:

    override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    
        let action = UIContextualAction(style: .destructive, title: nil) { action, view, completion in
            // Your swipe action code!
        }
        let label = UILabel()
        label.text = // Your swipe action text!
        label.font = // Your custom font!
        label.sizeToFit()
        action.image = UIImage(view: label)
    
        return UISwipeActionsConfiguration(actions: [action])
    }
    

    【讨论】:

      【解决方案2】:

      我最近发现了一种方法,通过使用按钮 titleLabel 而不是图像属性来执行此操作,这样您就可以保持对文本和图像进行操作的能力。

      正如你将看到的,我们需要做一些尴尬的事情......

      
      func tableView(_ tableView: UITableView, willBeginEditingRowAt indexPath: IndexPath) {
      
          if #available(iOS 13.0, *) {
              for subview in tableView.subviews {
                  if NSStringFromClass(type(of: subview)) == "_UITableViewCellSwipeContainerView" {
                      for swipeContainerSubview in subview.subviews {
                          if NSStringFromClass(type(of: swipeContainerSubview)) == "UISwipeActionPullView" {
                              for case let button as UIButton in swipeContainerSubview.subviews {
                                  button.titleLabel?.font = .systemFont(ofSize: 12)
                              }
                          }
                      }
                  }
              }
          } else {
              for subview in tableView.subviews {
                  if NSStringFromClass(type(of: subview)) == "UISwipeActionPullView" {
                      for case let button as UIButton in subview.subviews {
                          button.titleLabel?.font = .systemFont(ofSize: 12)
                      }
                  }
              }
          }
       }
      
      

      【讨论】:

      • 感谢大卫的代码!似乎您深入研究了内部实现细节,因此它可能很脆弱。一个好处是,可访问性可能比我的方法得到更好的支持:)
      【解决方案3】:

      已针对 Swift 5 和 iOS 13 更新

      以下功能允许您为滑动操作设置字体和色调。

      要开始使用,请将扩展名添加到 UITableView

      extension UITableView {
          /// Iterates over all subviews of a `UITableView` instance and applies the supplied font to all labels withing the UISwipeAction's array.
          /// - Parameter font: The font that should be applied to the labels.
          /// - Parameter tintColor: The tint color that should be applied to image views and labels
          /// - Parameter ignoreFirst: Whether or not the first swipe action should be ignored when applying tints
          public func setSwipeActionFont(_ font: UIFont, withTintColor tintColor: UIColor? = nil, andIgnoreFirst ignoreFirst: Bool = false) {
              for subview in self.subviews {
                  //Confirm that the view being touched is within a swipe container
                  guard NSStringFromClass(type(of: subview)) == "_UITableViewCellSwipeContainerView" else {
                      continue
                  }
      
                  //Re-iterate subviews and confirm that we are touching a swipe view
                  for swipeContainerSubview in subview.subviews {
                      guard NSStringFromClass(type(of: swipeContainerSubview)) == "UISwipeActionPullView" else {
                          continue
                      }
      
                      //Enumerate subviews and confirm that we are touching a button
                      for (index, view) in swipeContainerSubview.subviews.filter({ $0 is UIButton }).enumerated() {
                          //Set Font
                          guard let button = view as? UIButton else {
                              continue
                          }
                          button.titleLabel?.font = font
                          
                          //Set Tint Conditionally (based on index)
                          guard index > 0 || !ignoreFirst else {
                              continue
                          }
                          button.setTitleColor(tintColor, for: .normal)
                          button.imageView?.tintColor = tintColor
                      }
                  }
              }
          }
      }
      

      在您的委托中,将以下功能添加到您的 UITableViewDataSource.WillBeginEditing(UITableView, IndexPath) 方法中。根据需要替换字体和颜色参数。色调颜色是可选的。

      self?.tableView.setSwipeActionFont(.systemFont(ofSize: 24.0, withTintColor: .systemRed)
      

      【讨论】:

        【解决方案4】:

        针对目标 C

        创建一个方法

        - (UIImage *)createImageFromLabel:(UILabel *)label
        {
            UIGraphicsBeginImageContext(label.bounds.size);
        
            [label.layer renderInContext:UIGraphicsGetCurrentContext()];;
        
            UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        
            return image;
        }
        

        此方法将从您的标签返回图像。

        现在在 tableview 数据源方法中

        - (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath
        {
            UIContextualAction *action = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:nil handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
                
                //Your code here
            }];
        
            action.backgroundColor = [UIColor redColor];
        
            // Create label as you want view for delete button
            UILabel *label = [[UILabel alloc] init];
            label.font = [UIFont systemFontSize:14];
            label.text = @"Your Text";
            label.textColor = [UIColor whiteColor];
            [label sizeToFit];
            UIImage *image =  [self createImageFromLabel:label];
        
            action.image = image;
        
            UISwipeActionsConfiguration *actions = [UISwipeActionsConfiguration configurationWithActions:@[action]];
        
            return actions;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多