Mac Catalyst应用中Map View的Annotation View弹出框内容被截断求助
Mac Catalyst下Map View标注Callout文本截断问题解决方案
方法1:自定义Callout View(推荐)
系统默认Callout在Mac Catalyst环境下存在布局适配问题,直接自定义Callout内容视图可以完全控制文本显示:
class CustomCalloutView: UIView { private let addressLabel: UILabel = { let label = UILabel() label.numberOfLines = 0 label.lineBreakMode = .byWordWrapping label.translatesAutoresizingMaskIntoConstraints = false return label }() init(address: String) { super.init(frame: .zero) addSubview(addressLabel) addressLabel.text = address NSLayoutConstraint.activate([ addressLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8), addressLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8), addressLabel.topAnchor.constraint(equalTo: topAnchor, constant: 8), addressLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8) ]) // 模拟系统Callout样式 backgroundColor = .white layer.cornerRadius = 8 layer.borderColor = UIColor.lightGray.cgColor layer.borderWidth = 1 } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } // 在MapView的代理方法中配置标注视图 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { guard let customAnnotation = annotation as? YourAnnotationModel else { return nil } let reuseID = "LocationPin" var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseID) as? MKPinAnnotationView if pinView == nil { pinView = MKPinAnnotationView(annotation: customAnnotation, reuseIdentifier: reuseID) pinView?.canShowCallout = true // 替换系统默认详情视图为自定义视图 pinView?.detailCalloutAccessoryView = CustomCalloutView(address: customAnnotation.address) pinView?.calloutOffset = CGPoint(x: -5, y: 5) } else { pinView?.annotation = customAnnotation // 更新自定义视图的文本内容 if let calloutView = pinView?.detailCalloutAccessoryView as? CustomCalloutView { calloutView.addressLabel.text = customAnnotation.address } } return pinView }
方法2:调整系统Callout的文本约束(临时方案)
通过遍历系统Callout的子视图,修改详情Label的布局属性,注意该方法可能随系统版本更新失效:
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) { // 延迟执行确保Callout已完成加载 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { view.calloutView?.subviews.forEach { subview in guard let label = subview as? UILabel, let address = (view.annotation as? YourAnnotationModel)?.address, label.text == address else { return } label.numberOfLines = 0 label.preferredMaxLayoutWidth = 250 // 设置最大换行宽度 label.sizeToFit() } } }
方法3:清理文本内容
检查地址文本是否包含多余换行或特殊字符,统一处理后再赋值:
// 清理地址文本 let cleanedAddress = customAnnotation.address .replacingOccurrences(of: "\n", with: " ") .trimmingCharacters(in: .whitespacesAndNewlines)
内容的提问来源于stack exchange,提问作者Manish
相关产品推荐
相关产品推荐

