Ios 设置单元格内视图的角半径时出现问题?
我有一个自定义的Ios 设置单元格内视图的角半径时出现问题?,ios,uitableview,cornerradius,Ios,Uitableview,Cornerradius,我有一个自定义的UITableView单元格。我正在设置它的左下角和右下角半径。我正在cellForAtindexPath中设置角半径。下面是代码 if indexPath.row == 9 { recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10) recipeInfoCell.layoutSubviews() recipeInfoCell.layoutIfNee
UITableView
单元格。我正在设置它的左下角和右下角半径。我正在cellForAtindexPath
中设置角半径。下面是代码
if indexPath.row == 9 {
recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
recipeInfoCell.layoutSubviews()
recipeInfoCell.layoutIfNeeded()
} else {
recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 0)
recipeInfoCell.layoutSubviews()
}
现在,当我第一次启动tableview时,它没有设置任何角半径。但当我再次滚动时,它正在设置角半径
我创建了UIView
的扩展,其中有一个函数用于设置角半径
func roundCorners(corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
请告诉我如何解决这个问题?为了在swift中获得它,我只使用创建UIButton的一个子类,如下所示 (在项目的任何.swift文件中) 然后在相同或不同的.swift文件中定义以下方法,如下所示
//MARK: - UIView Property Class
@IBDesignable open class CView : CustomView{
@IBInspectable dynamic open var borderColor: UIColor = UIColor.clear{
didSet{
updateBorderColor()
}
}
@IBInspectable dynamic open var borderWidth: CGFloat = 1.0{
didSet{
updateBorderWidth()
}
}
@IBInspectable dynamic open var cornerRadius: CGFloat = 0.0{
didSet{
updateBorderRadius()
}
}
@IBInspectable dynamic open var shadowColor: UIColor?{
didSet{
updateShadowColor()
}
}
@IBInspectable dynamic open var shadowRadius: CGFloat = 0.0{
didSet{
updateShadowRadius()
}
}
@IBInspectable dynamic open var shadowOpacity: Float = 0.0{
didSet{
updateShadowOpacity()
}
}
@IBInspectable dynamic open var shadowOffSet: CGSize = CGSize(width: 0.0, height: 0.0){
didSet{
updateShadowOffset()
}
}
//Update Borders Properties
open func updateBorderColor(){
self.layer.borderColor = borderColor.cgColor
}
open func updateBorderRadius(){
self.layer.cornerRadius = cornerRadius
}
open func updateBorderWidth(){
self.layer.borderWidth = borderWidth
}
//Update Shadow Properties
open func updateShadowColor(){
self.layer.shadowColor = shadowColor?.cgColor
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
open func updateShadowOpacity(){
self.layer.shadowOpacity = shadowOpacity
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
open func updateShadowRadius(){
self.layer.shadowRadius = shadowRadius
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
open func updateShadowOffset(){
self.layer.shadowOffset = CGSize(width: shadowOffSet.width, height: shadowOffSet.height)
self.layer.shadowColor = shadowColor?.cgColor
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
}
然后,只需在设计时在脚本中为任何视图控制器分配CView
类,并在该视图的属性检查器中为该侧的属性提供所需的值
情节提要
1) 类的视图
2) 像这样设置属性
//MARK: - UIView Property Class
@IBDesignable open class CView : CustomView{
@IBInspectable dynamic open var borderColor: UIColor = UIColor.clear{
didSet{
updateBorderColor()
}
}
@IBInspectable dynamic open var borderWidth: CGFloat = 1.0{
didSet{
updateBorderWidth()
}
}
@IBInspectable dynamic open var cornerRadius: CGFloat = 0.0{
didSet{
updateBorderRadius()
}
}
@IBInspectable dynamic open var shadowColor: UIColor?{
didSet{
updateShadowColor()
}
}
@IBInspectable dynamic open var shadowRadius: CGFloat = 0.0{
didSet{
updateShadowRadius()
}
}
@IBInspectable dynamic open var shadowOpacity: Float = 0.0{
didSet{
updateShadowOpacity()
}
}
@IBInspectable dynamic open var shadowOffSet: CGSize = CGSize(width: 0.0, height: 0.0){
didSet{
updateShadowOffset()
}
}
//Update Borders Properties
open func updateBorderColor(){
self.layer.borderColor = borderColor.cgColor
}
open func updateBorderRadius(){
self.layer.cornerRadius = cornerRadius
}
open func updateBorderWidth(){
self.layer.borderWidth = borderWidth
}
//Update Shadow Properties
open func updateShadowColor(){
self.layer.shadowColor = shadowColor?.cgColor
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
open func updateShadowOpacity(){
self.layer.shadowOpacity = shadowOpacity
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
open func updateShadowRadius(){
self.layer.shadowRadius = shadowRadius
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
open func updateShadowOffset(){
self.layer.shadowOffset = CGSize(width: shadowOffSet.width, height: shadowOffSet.height)
self.layer.shadowColor = shadowColor?.cgColor
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
}
3) 这将显示像这样的设计的侧面视图
//MARK: - UIView Property Class
@IBDesignable open class CView : CustomView{
@IBInspectable dynamic open var borderColor: UIColor = UIColor.clear{
didSet{
updateBorderColor()
}
}
@IBInspectable dynamic open var borderWidth: CGFloat = 1.0{
didSet{
updateBorderWidth()
}
}
@IBInspectable dynamic open var cornerRadius: CGFloat = 0.0{
didSet{
updateBorderRadius()
}
}
@IBInspectable dynamic open var shadowColor: UIColor?{
didSet{
updateShadowColor()
}
}
@IBInspectable dynamic open var shadowRadius: CGFloat = 0.0{
didSet{
updateShadowRadius()
}
}
@IBInspectable dynamic open var shadowOpacity: Float = 0.0{
didSet{
updateShadowOpacity()
}
}
@IBInspectable dynamic open var shadowOffSet: CGSize = CGSize(width: 0.0, height: 0.0){
didSet{
updateShadowOffset()
}
}
//Update Borders Properties
open func updateBorderColor(){
self.layer.borderColor = borderColor.cgColor
}
open func updateBorderRadius(){
self.layer.cornerRadius = cornerRadius
}
open func updateBorderWidth(){
self.layer.borderWidth = borderWidth
}
//Update Shadow Properties
open func updateShadowColor(){
self.layer.shadowColor = shadowColor?.cgColor
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
open func updateShadowOpacity(){
self.layer.shadowOpacity = shadowOpacity
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
open func updateShadowRadius(){
self.layer.shadowRadius = shadowRadius
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
open func updateShadowOffset(){
self.layer.shadowOffset = CGSize(width: shadowOffSet.width, height: shadowOffSet.height)
self.layer.shadowColor = shadowColor?.cgColor
self.clipsToBounds = false;
self.layer.masksToBounds = false;
}
}
有了它,您甚至可以在设计生成器中直接看到阴影或角半径,即在故事板视图的侧面,如第三幅图像。我认为在cellForRow atIndexPath中设置角半径不是一个好主意。原因是,此函数在UITableView的生命周期内被多次调用,您只需设置一次角半径,并且在初始化单元格时也需要设置角半径。基于indexPath更改拐角半径也会影响UITableView的性能 更好的方法是创建两个单元格,一个角半径为0,另一个角半径为10,并基于indexPath使用这些单元格 然后,您可以将cornerRadius集逻辑放入自定义单元格的layoutSubview函数中 如果只想在tableView方法中执行此操作,正确的方法是在willDisplayCell中执行此操作,因为在该调用之后,将调用中的单元格的layoutSubviews函数
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row % 2 == 0 {
let path = UIBezierPath(roundedRect: cell.contentView.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 10, height: 10))
let mask = CAShapeLayer()
mask.path = path.cgPath
cell.contentView.layer.mask = mask
} else {
let path = UIBezierPath(roundedRect: cell.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 0, height: 0))
let mask = CAShapeLayer()
mask.path = path.cgPath
cell.contentView.layer.mask = mask
}
}
更新:2017年5月19日
如果要圆化并放置阴影的视图的大小与单元格的内容视图的大小相同,则上述概念可以正常工作。但如果有什么不同的话,那就行不通了
出现上述语句的原因是,在调用willDisplayCell时,上面的代码正在使用cell.contentView.bounds
,其他视图尚未计算。因此,当我们使用另一个视图时,我们必须使用该视图的边界来计算遮罩的帧,这与实际的帧不同
读了一点之后,我发现,要做这种事情,需要重写UITableViewCell的draw(\urect:CGRect)
函数。因为此时,视图的大小已正确计算,我们可以创建正确的帧
以下是自定义UITableViewCell类的代码:
var shadowLayer = CAShapeLayer()
override func draw(_ rect: CGRect) {
let path = UIBezierPath(roundedRect: self.outerView.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 10, height: 10))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.outerView.layer.mask = mask
// Handle Cell reuse case
shadowLayer.removeFromSuperlayer()
shadowLayer.shadowPath = path.cgPath
shadowLayer.frame = self.outerView.layer.frame
print(shadowLayer.frame)
shadowLayer.shadowOffset = CGSize(width: 0, height: 0)
shadowLayer.shadowColor = UIColor.black.cgColor
shadowLayer.shadowOpacity = 0.9
self.contentView.layer.insertSublayer(shadowLayer, below: self.outerView.layer)
super.draw(rect)
}
enum cellStyle: Int {
case Normal = 0, Rounded
}
class CustomTableCell:UITableViewCell {
var cellType: Int = 0 {
didSet {
let maskLayer = CAShapeLayer()
let cell: cellStyle = cellStyle(rawValue: cellType)!
switch cell {
case .Normal:
let normal = UIBezierPath(roundedRect: self.viewMain.bounds, byRoundingCorners: [.bottomLeft, .bottomRight], cornerRadii: CGSize(width: 0, height: 0))
maskLayer.path = normal.cgPath
self.viewMain.layer.mask = maskLayer
case .Rounded:
let rounded = UIBezierPath(roundedRect: self.viewMain.bounds, byRoundingCorners: [.bottomLeft, .bottomRight], cornerRadii: CGSize(width: 10, height: 10))
maskLayer.path = rounded.cgPath
self.viewMain.layer.mask = maskLayer
}
}
}
}
尝试在自定义
UITableViewCell的layoutSubviews()
中编写这些代码行
override func layoutSubviews() {
super.layoutSubviews()
self.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
}
在主队列中放置圆角代码,如下所示:
if indexPath.row == 9 { dispatch_async(dispatch_get_main_queue(),{
recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
})} else{
dispatch_async(dispatch_get_main_queue(),{
recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 0)
}) }
如果我理解正确的话,您希望一个特定的单元格在拐角处。这是我的解决办法。虽然我有点晚了,但我尽力帮助别人。:)我只是将我的解决方案添加为图片
第1步:
创建了一个自定义单元格并执行了一些必要的步骤
下面是左下角和右下角圆角的代码。很抱歉,编码风格不好:
下面是我的视图控制器的配置,用于显示带有圆形单元格的tableView
下面是关键时刻:
我引用了()并修改了代码,现在它对我起作用了:
将以下代码添加到自定义单元格类:
var shadowLayer = CAShapeLayer()
override func draw(_ rect: CGRect) {
let path = UIBezierPath(roundedRect: self.outerView.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 10, height: 10))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.outerView.layer.mask = mask
// Handle Cell reuse case
shadowLayer.removeFromSuperlayer()
shadowLayer.shadowPath = path.cgPath
shadowLayer.frame = self.outerView.layer.frame
print(shadowLayer.frame)
shadowLayer.shadowOffset = CGSize(width: 0, height: 0)
shadowLayer.shadowColor = UIColor.black.cgColor
shadowLayer.shadowOpacity = 0.9
self.contentView.layer.insertSublayer(shadowLayer, below: self.outerView.layer)
super.draw(rect)
}
enum cellStyle: Int {
case Normal = 0, Rounded
}
class CustomTableCell:UITableViewCell {
var cellType: Int = 0 {
didSet {
let maskLayer = CAShapeLayer()
let cell: cellStyle = cellStyle(rawValue: cellType)!
switch cell {
case .Normal:
let normal = UIBezierPath(roundedRect: self.viewMain.bounds, byRoundingCorners: [.bottomLeft, .bottomRight], cornerRadii: CGSize(width: 0, height: 0))
maskLayer.path = normal.cgPath
self.viewMain.layer.mask = maskLayer
case .Rounded:
let rounded = UIBezierPath(roundedRect: self.viewMain.bounds, byRoundingCorners: [.bottomLeft, .bottomRight], cornerRadii: CGSize(width: 10, height: 10))
maskLayer.path = rounded.cgPath
self.viewMain.layer.mask = maskLayer
}
}
}
}
在您的ViewController->cellForRowAt--在主队列上调用下面的代码
DispatchQueue.main.async {
if totalRows == index + 1 { //write your condition
cell.cellType = cellStyle.Rounded.rawValue
} else {
cell.cellType = cellStyle.Normal.rawValue
}
cell.layoutSubviews()
cell.layoutIfNeeded()
}
这对我很有用:
view.clipsToBounds = true
view.layer.cornerRadius = value
view.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMinXMaxYCorner]
看到这一点:我正在做的完全正确,但问题是创建单元格时不显示角半径。当我滚动tableview时,只设置角半径,第二次设置角半径,这意味着它不是角半径问题。它的表视图问题。所以,检查单元格中索引路径行的条件。但是当我设置像view.cornerRadius=10这样的角半径时,它就变好了。您是否尝试将此代码放入“willDisplayCell”中?此外,背景颜色的修改也放在那里。我不能采用这种方法。你没有得到什么部分?我不想使用其他单元格,因为我在tableview中已经使用了太多的单元格。这可能会解决我的问题,但我想知道我的代码有什么问题。当我仅通过bazier路径设置角半径时,我会遇到问题。当我在没有bazier路径的情况下设置角半径时,我会遇到问题我的代码运行良好。我将遵循您的方法,以确保这是一种解决我的问题的方法。我已尝试过您的方法,但这不适用于meCorner raius,即使我添加了角半径以便在AwakeFromnib中查看,我的要求与此不同。对不起,您想在评论中说什么?你能说得更具体一点吗?我解释了为什么这段代码在awakefromnib中不起作用。为什么我需要重写这个方法,因为在awakefromnib,子视图的框架没有加载,这就是为什么。这里的outerView是什么?由于该引用,它将不会编译。“没有成员'outerView'”