因在项目中多次遇到了单选,多选的需求,所以在这里总结下,以便下次可以有个参考或者直接可以用的。
OC版
在DEMO中主要实现了以下功能
- 分组,按钮布局自适应文字大小
- 单选多选,每个组分别设置单选多选
- 设置默认选择项
分组是根据每个组的 titleArr
来判断的,
传入数据源
func setDataSource(contetnArr : Array<Any>, titleArr : Array<String>)
进行分组
//设置默认的值,使保存值的数组是按照group的顺序来保存,便于后面对相应的group的值进行增改
for (index,title) in titleArr.enumerated() {
saveSelButValueArr.append("")
saveSelGroupIndexeArr.append("")
frameRect = setupGroupAndStream(content: contetnArr[index] as! Array<Any>, titleStr: title, currFrame: frameRect, groupId: index)
}
设置滚动视图的滚动范围
//设置滚动范围
scrollView.contentSize = CGSize(width: UIScreen.main.bounds.width, height: frameRect.size.height + frameRect.origin.y + 20)
文字自适应
let but_width = calcuateLabSizeWidth(str: value as! String, font:content_titleFont, maxHeight: CGFloat(content_height)) + 20
//计算每个button的 X
margin_x = CGFloat(alineButWidth) + CGFloat(content_x)
//计算一行的宽度
alineButWidth = CGFloat(content_x) + but_width + CGFloat(alineButWidth)
//判断是否需要换行
if alineButWidth >= self.frame.size.width{
margin_x = CGFloat(content_x)
alineButWidth = margin_x + but_width
content_totalHeight = current_rect.size.height + current_rect.origin.y + CGFloat(content_x)
}
// print("margin_x = \(margin_x)")
sender.frame = CGRect(x: margin_x, y: content_totalHeight, width: but_width, height: CGFloat(content_height))
//临时保存frame,以进行下一次坐标计算
current_rect = sender.frame
设置默认选中
//MARK:---设置默认---单选
private func setDefaultSingleSelect(index : Int , groupId : Int ,value : String, sender : UIButton, content : Array<Any>){
//单选
let valueStr = "\(index)/\(value)"
if defaultSelSingleIndeArr.isEmpty{
assert( !(defaultSelIndex > content.count - 1), "在groupId = \(groupId) 设置默认选中项不能超过\(content.count - 1)")
if index == defaultSelIndex{
sender.isSelected = true
sender.backgroundColor = content_backSelColor
saveSelButValueArr[groupId] = valueStr
}
}else{
assert(!((defaultSelSingleIndeArr[groupId] as? Int)! > content.count - 1), "在groupId = \(groupId) 设置默认选中项不能超过\(content.count - 1)")
if index == defaultSelSingleIndeArr[groupId] as? Int{
sender.isSelected = true
sender.backgroundColor = content_backSelColor
saveSelButValueArr[groupId] = valueStr
}
}
saveSelGroupIndexeArr[groupId] = String(groupId)
}
//MARK:---设置默认---多选
private func setDefaultMultipleSelect(index : Int , groupId : Int ,value : String, sender : UIButton, content : Array<Any>) -> Array<Any>{
let content = defaultSelIndexArr[groupId]
var tempSaveSelIndexArr = Array<Any>()
if content is Int{
if index == content as! Int{
sender.isSelected = true
sender.backgroundColor = content_backSelColor
tempSaveSelIndexArr.append("\(index)/\(value)")
}
}
if content is Array<Any>{
for contenIndex in content as! Array<Any>{
if index == contenIndex as! Int{
sender.isSelected = true
sender.backgroundColor = content_backSelColor
tempSaveSelIndexArr.append("\(index)/\(value)")
continue
}
}
}
saveSelGroupIndexeArr[groupId] = String(groupId)
return tempSaveSelIndexArr
}
单选,多选
//MARK:---单选
private func singalSelectEvent(sender : UIButton){
var valueStr : String = ""
let tempDetailArr = dataSourceArr[sender.tag / 100] as! Array<Any>
if sender.isSelected {
for (index, _) in tempDetailArr.enumerated(){
if index + 1 == sender.tag % 100{
sender.isSelected = true
sender.backgroundColor = content_backSelColor
continue
}
let norSender = scrollView.viewWithTag((sender.tag / 100) * 100 + index + 1) as! UIButton
norSender.isSelected = false
norSender.backgroundColor = content_backNorColor
}
valueStr = "\(sender.tag % 100 - 1)/\(tempDetailArr[sender.tag % 100 - 1])"
//闭包传值
if currentSelValueClosure != nil {
currentSelValueClosure!(valueStr,sender.tag % 100 - 1,sender.tag / 100)
}
//代理传值
delegate?.currentSelValueWithDelegate?(valueStr: valueStr, index: sender.tag % 100 - 1, groupId: sender.tag / 100)
}else{
sender.backgroundColor = content_backNorColor
}
//保存选中的值
saveSelButValueArr[sender.tag / 100] = valueStr
//保存groupId
saveSelButValueArr[sender.tag / 100] as! String == "" ? (saveSelGroupIndexeArr[sender.tag / 100] = "") : (saveSelGroupIndexeArr[sender.tag / 100] = String(sender.tag / 100))
}
//MARK:---多选
private func multipleSelectEvent(sender : UIButton){
var valueStr = ""
var tempSaveArr = Array<Any>()
if ((saveSelButValueArr[sender.tag / 100]) is Array<Any>){
tempSaveArr = saveSelButValueArr[sender.tag / 100] as! Array<Any>
}else{
tempSaveArr.append(saveSelButValueArr[sender.tag / 100])
}
let tempDetailArr = dataSourceArr[sender.tag / 100] as! Array<Any>
valueStr = "\(sender.tag % 100 - 1)/\(tempDetailArr[sender.tag % 100 - 1])"
if sender.isSelected {
sender.backgroundColor = content_backSelColor
//不存在相同的元素
tempSaveArr.append(valueStr)
//闭包传值
if currentSelValueClosure != nil {
currentSelValueClosure!(valueStr,sender.tag % 100 - 1,sender.tag / 100)
}
//代理传值
delegate?.currentSelValueWithDelegate?(valueStr: valueStr, index: sender.tag % 100 - 1, groupId: sender.tag / 100)
}else{
sender.backgroundColor = content_backNorColor
//获取元素的下标
let index : Int = tempSaveArr.index(where: {$0 as! String == valueStr})!
tempSaveArr.remove(at: index)
}
saveSelButValueArr[sender.tag / 100] = tempSaveArr
tempSaveArr.isEmpty ? (saveSelGroupIndexeArr[sender.tag / 100] = "") : (saveSelGroupIndexeArr[sender.tag / 100] = String(sender.tag / 100))
}
计算文字宽度
//MARK:---计算文字宽度
private func calcuateLabSizeWidth(str : String, font : UIFont, maxHeight : CGFloat) -> CGFloat{
let attributes = [kCTFontAttributeName: font]
let norStr = NSString(string: str)
let size = norStr.boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: maxHeight), options: .usesLineFragmentOrigin, attributes: attributes as [NSAttributedStringKey : Any], context: nil)
return size.width
}
记录到此结束,代码简单。
DEMO-GitHub-地址
DEMO-Bitbucket-地址