Left or right align shouldShowMenuForRowAt menu for a custom UITableView cell

↘锁芯ラ 提交于 2021-01-24 11:14:59

问题


I have a UITableView that I am using for showing chat messages. The cells of this table view are either left or right-aligned and have dynamic width. The menu displayed by shouldShowMenuForRowAt is shown at the horizontal center of the table view cell. Is there a way to shift it to the left or the right edge?

    func tableView(_ tableView: UITableView, shouldShowMenuForRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
        return action == #selector(copy(_:))
    }

    func tableView(_ tableView: UITableView, performAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) {
        if action == #selector(copy(_:)) {
            if let cell = tableView.cellForRow(at: indexPath) as? DiscussionChatMessageCell {
                let pasteboard = UIPasteboard.general
                pasteboard.string = cell.getMessageLabel().text
            }
        }
    }

Output:

Can the actions for cells be left and right aligned?

Message Cell:

class DiscussionChatMessageCell: UITableViewCell {
    
    private let messageLabel: UITextView
    private let senderNameLabel: UILabel
    private let messageSentTimeLabel: UILabel
    private let messageBubble: UIView
    
    private var bubbleLeadingConstraint: NSLayoutConstraint!
    private var bubbleTrailingConstraint: NSLayoutConstraint!
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        
        messageLabel = UITextView()
        senderNameLabel = UILabel()
        messageSentTimeLabel = UILabel()
        messageBubble = UIView()
        
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        selectionStyle = .none
        
        self.contentView.addSubview(messageBubble)
        messageBubble.translatesAutoresizingMaskIntoConstraints = false
        
        messageBubble.addSubview(senderNameLabel)
        senderNameLabel.translatesAutoresizingMaskIntoConstraints = false
        senderNameLabel.numberOfLines = 0
        senderNameLabel.lineBreakMode = .byCharWrapping
        senderNameLabel.font =  getFont(name: .HelveticaNeueBold, size: .large)
        senderNameLabel.textColor = .white
        
        messageBubble.addSubview(messageLabel)
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        
        messageLabel.isEditable = false
        messageLabel.isSelectable = false
        messageLabel.dataDetectorTypes = .all
        messageLabel.textContainer.lineBreakMode = .byWordWrapping
        messageLabel.isScrollEnabled = false
        messageLabel.backgroundColor = .clear
        messageLabel.isUserInteractionEnabled = true
        
//        messageLabel.numberOfLines = 0
//        messageLabel.lineBreakMode = .byWordWrapping
        messageLabel.font = getFont(name: .HelveticaNeue, size: .medium)
        
        messageBubble.addSubview(messageSentTimeLabel)
        messageSentTimeLabel.translatesAutoresizingMaskIntoConstraints = false
        messageSentTimeLabel.lineBreakMode = .byCharWrapping
        messageSentTimeLabel.numberOfLines = 0
        messageSentTimeLabel.font = getFont(name: .HelveticaNeueItalic, size: .small)
        
        // set hugging and compression resistance for Name label
        senderNameLabel.setContentCompressionResistancePriority(.required, for: .vertical)
        senderNameLabel.setContentHuggingPriority(.required, for: .vertical)
        
        // create bubble Leading and Trailing constraints
        bubbleLeadingConstraint = messageBubble.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 10)
        bubbleTrailingConstraint = messageBubble.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -10)
        
        // priority will be changed in configureCell()
        bubbleLeadingConstraint.priority = .defaultHigh
        bubbleTrailingConstraint.priority = .defaultLow
        
        NSLayoutConstraint.activate([
            
            bubbleLeadingConstraint,
            bubbleTrailingConstraint,
            
            messageBubble.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10),
            messageBubble.bottomAnchor.constraint(equalTo:  self.contentView.bottomAnchor, constant: -10),
            
            messageBubble.widthAnchor.constraint(lessThanOrEqualTo: self.contentView.widthAnchor, constant: -100),
            
            senderNameLabel.topAnchor.constraint(equalTo: messageBubble.topAnchor, constant: 10),
            senderNameLabel.leadingAnchor.constraint(equalTo: messageBubble.leadingAnchor, constant: 10),
            senderNameLabel.trailingAnchor.constraint(equalTo: messageBubble.trailingAnchor, constant: -10),
            
            messageLabel.topAnchor.constraint(equalTo: senderNameLabel.bottomAnchor, constant: 10),
            messageLabel.leadingAnchor.constraint(equalTo: messageBubble.leadingAnchor, constant: 10),
            messageLabel.trailingAnchor.constraint(equalTo: messageBubble.trailingAnchor, constant: -10),
            messageLabel.bottomAnchor.constraint(equalTo: messageSentTimeLabel.topAnchor, constant: -10),
            
            messageSentTimeLabel.leadingAnchor.constraint(equalTo: messageBubble.leadingAnchor, constant: 10),
            messageSentTimeLabel.trailingAnchor.constraint(equalTo: messageBubble.trailingAnchor, constant: -10),
            messageSentTimeLabel.bottomAnchor.constraint(equalTo: messageBubble.bottomAnchor, constant: -10),
            
        ])
        
        // corners will have radius: 10
        messageBubble.layer.cornerRadius = 10
    }
    
    func getMessageLabel() -> UITextView {
        return messageLabel
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func configureCell(message: DiscussionMessage, isSender: Bool, previousMessage: DiscussionMessage?) {
        
        let senderName = isSender ? "You" : message.userName
        senderNameLabel.text = senderName + " " + message.userCountryEmoji
        
        let date = Date(timeIntervalSince1970: message.messageTimestamp)
        
        let dayTimePeriodFormatter = DateFormatter()
        dayTimePeriodFormatter.timeZone = .current
        
        dayTimePeriodFormatter.dateFormat = "hh:mm a"
        let dateString = dayTimePeriodFormatter.string(from: date)
        
        messageLabel.text = message.message
        
        messageSentTimeLabel.text = dateString
        
        messageLabel.textColor = isSender ? .black : .white
        senderNameLabel.textColor = isSender ? .black : .white
        messageSentTimeLabel.textColor = isSender ? .black : .white
        messageSentTimeLabel.textAlignment = isSender ? .right : .left
        
        bubbleLeadingConstraint.priority = isSender ? .defaultLow : .defaultHigh
        bubbleTrailingConstraint.priority = isSender ? .defaultHigh : .defaultLow
        
        messageBubble.backgroundColor = isSender ? accentColor : .gray
        
        let senderCorners: CACornerMask = [.layerMinXMinYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner]
        let nonSenderCorners: CACornerMask =  [.layerMinXMinYCorner, .layerMaxXMinYCorner, .layerMaxXMaxYCorner]
        
        
        messageBubble.layer.maskedCorners = isSender ?
            // topLeft, topRight, bottomRight
            senderCorners
            :
            // topLeft, topRight, bottomLeft
            nonSenderCorners
//
//        if let previousMessage = previousMessage {
//            if message.userEmailAddress == previousMessage.userEmailAddress && message.userCountryCode == previousMessage.userCountryCode && isSender {
//                senderNameLabel.isHidden = true
//            } else {
//                senderNameLabel.isHidden = false
//            }
//        } else {
//            senderNameLabel.isHidden = false
//        }
    }
}

来源:https://stackoverflow.com/questions/65840591/left-or-right-align-shouldshowmenuforrowat-menu-for-a-custom-uitableview-cell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!