如何调整UICalendarView中自定义装饰视图CustomView的尺寸?
解决UICalendarView自定义装饰视图尺寸不生效的问题
问题原因
UICalendarView的自定义装饰视图采用Auto Layout布局,直接设置frame会被系统忽略。图片装饰的size参数本质是帮视图设置了固有内容尺寸(intrinsicContentSize),而自定义视图需要自己提供这个尺寸信息。
解决方案:指定固有内容尺寸
让自定义视图返回正确的intrinsicContentSize,系统会依据这个值来布局装饰视图,有两种实现方式:
方式1:自定义UIView子类重写intrinsicContentSize
func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? { return .customView(addActivityCircle) } private func addActivityCircle() -> UIView { let view = ActivityCircleView() view.backgroundColor = .red return view } class ActivityCircleView: UIView { override var intrinsicContentSize: CGSize { // 返回你需要的尺寸,示例为50x50 return CGSize(width: 50, height: 50) } }
方式2:直接设置视图的intrinsicContentSize(无需子类)
func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? { return .customView(addActivityCircle) } private func addActivityCircle() -> UIView { let view = UIView() view.backgroundColor = .red // 直接指定固有内容尺寸 view.intrinsicContentSize = CGSize(width: 50, height: 50) return view }
进阶:随日历单元格动态调整尺寸
如果需要装饰视图尺寸跟随日历单元格大小变化,可以在decorationFor方法中获取单元格布局信息,再调整尺寸:
func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? { // 获取日历单元格尺寸(iOS 16+支持) let cellSize = calendarView.calendarLayout.cellSize // 设置装饰视图为单元格尺寸的一半 let decorSize = CGSize(width: cellSize.width * 0.5, height: cellSize.height * 0.5) let view = UIView() view.backgroundColor = .red view.intrinsicContentSize = decorSize return .customView(view) }
补充说明
Apple Fitness的活动环装饰本质也是自定义视图:通过重写draw(_ rect:)绘制环形进度,同时设置合适的intrinsicContentSize控制显示大小。只要确保自定义视图返回正确的固有尺寸,就能实现预期的显示效果。
内容的提问来源于stack exchange,提问作者Mel
相关产品推荐
相关产品推荐

