实现一个自定义的Alert
为何需要自定义Alert?
这次主要遇到问题是:在一个页面内添加了一个UIAlertViewController以实现添加单词,并在其中加入词性选择的列表,如图:
但是会发现在UIAlertViewController里面添加的按钮“选中”没有办法响应,在查了资料,问了人之后知道这是由于这个按钮已经超出UIAlertViewController的范围,故无法反映,而又因为给定UIAlertViewController的属性比较有限,无法解决这个问题,就需要自己写一个Alert了。
第一次尝试
思路
想到的第一个解决方法是:干脆让他弹出一个新的视图,自己写一个继承于UIViewController、效果类似于UIAlertViewController效果的视图,设置背景色、alpha值,添加标题label、taxtfeilds、buttons,也的确可以实现,但是视图的层次自己搞的有些乱了,而且也有些麻烦。发现作为一个viewController的子类,如果原本的视图就含有图片,那么,在你的viewController弹到上层时,下面的图片变成了黑色,所以就需要转变思路,建议改用继承UIView的子类实现。
第二次尝试
思路
这次改用了继承UIView的子类实现,主要需要实现的就是重写init()方法和layoutSubviews()方法,并需要在layoutSubviews()方法中写布局。
1.重写init初始化
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor(red:0, green:0, blue:0, alpha:0.8)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}//必不可少,Swift语言强制要求
2.一些功能实现
func setupSubViews(title: String,subTitle: String){//设置标题和副标题
view = UIButton(type:UIButtonType.roundedRect)
view?.layer.cornerRadius = SCREENSIZE.width/48
view?.backgroundColor = UIColor.white
titleView = UILabel(frame: defaultFrame)
titleView?.text = title
titleView?.textColor = UIColor.black
titleView?.textAlignment = .center
titleView?.backgroundColor = UIColor.white
subTitleView = UITextView(frame: defaultFrame)
subTitleView?.text = subTitle
subTitleView?.textAlignment = .center
subTitleView?.backgroundColor = UIColor.white
subTitleView?.isEditable = false
self.addSubview(view!)
self.addSubview(titleView!)
self.addSubview(subTitleView!)
}
func setupTextFeild(numberOfTextFeilds: Int){//textFeilds = [textFeild]()
Tnum = numberOfTextFeilds
var i:Int = 0
while (i < numberOfTextFeilds) {
let text = UITextField(frame: defaultFrame)
textFeilds.append(text)
textFeilds[i].backgroundColor = UIColor.white
textFeilds[i].borderStyle = .none
self.addSubview(textFeilds[i])
i += 1
}
}
func setupButton(numberOfButtons: Int){//buttons = [UIButton]()
Bnum = numberOfButtons
var i:Int = 0
while (i < numberOfButtons) {
let button = UIButton(frame: defaultFrame)
buttons.append(button)
buttons[i].layer.cornerRadius = SCREENSIZE.width/64
buttons[i].backgroundColor = UIColor.white
buttons[i].setTitleColor(UIColor.black, for: UIControlState())
self.addSubview(buttons[i])
i += 1
}
}
3.重写layoutSubviews方法
override func layoutSubviews() {
super.layoutSubviews()
self.frame = CGRect(x:0,y:0,width:SCREENSIZE.width,height:SCREENSIZE.height)//修改!非常重要!!!相当于设定了相应的区域!如果没有在某些情况下弹出框无法响应触摸等动作!也可以通过设置该属性管理响应区域!Bingo!
let xSize = Int(SCREENSIZE.width/4)
let yOringalSize = Int(SCREENSIZE.height/2)-(140+Tnum*40)/2
view?.frame = CGRect(x:SCREENSIZE.width/4-CGFloat(20),y:CGFloat(yOringalSize),width:SCREENSIZE.width/2+CGFloat(40),height:CGFloat(160+Tnum*40))
titleView?.frame = CGRect(x:SCREENSIZE.width/4,y:CGFloat(yOringalSize+20),width:SCREENSIZE.width/2,height:40)
subTitleView?.frame = CGRect(x:SCREENSIZE.width/4,y:CGFloat(yOringalSize+60),width:SCREENSIZE.width/2,height:40)
var i:Int = 0
while (i < Tnum) {
textFeilds[i].frame = CGRect(x:xSize,y:yOringalSize+100+40*i,width:Int(SCREENSIZE.width/2),height:40)
i += 1
}
var j:Int = 0
let width = Int(SCREENSIZE.width/2)/Bnum
let gapSize = width/16
var periorPos = xSize - gapSize/2 + gapSize/4
while (j < Bnum) {
buttons[j].frame = CGRect(x:periorPos+gapSize/2,y:yOringalSize+100+40*i,width:width-gapSize,height:40)
periorPos += width
j += 1
}
}
4.调用
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let frame = UIScreen.main.bounds
let Alert = AlertView.init(frame: frame)
Alert.setupSubViews(title: "Title", subTitle: "subTitle")
Alert.setupTextFeild(numberOfTextFeilds: 2)
Alert.textFeilds[0].placeholder = "Text1"
Alert.textFeilds[1].placeholder = "Text2"
Alert.setupButton(numberOfButtons: 2)
Alert.buttons[0].setTitle("确定", for: UIControlState())
Alert.buttons[1].setTitle("取消", for: UIControlState())
self.view.addSubview(Alert)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
写在后面
写的是一个很简单的Alert弹出框,很多功能还得调用的时候再写,不够完善但是在自己自定义的过程中还是学到了很多布局、功能设计等等方面的东西,分享出来希望能对在看的你有一定帮助。