实现效果如下:
需求:
【 * - 拼写单词,实现将单词的顺序打乱,并增添其他可选字母*】
【* - 实现简单的记忆功能,使得拼写更加人性化*】
【* - 按钮变色,全选后变色,判断变色等一系列视觉效果*】
【* - 优化算法,提高可执行性,效率*】
第一种-不具有记忆能力的键盘
(也就是只能删除,不能单独取消某一个字母)
核心算法
自定义键盘下载地址(http://download.csdn.net/detail/xoxo_x/9698846)
func putWordToStingArray(word:String) {
wordArray.removeAll()
print("word -- \(word)")
for char in word.characters {
print("\(char)")
wordArray.append("\(char)")
for (i,item) in charArray.enumerate() {
if "\(char)" == item {
charArray.removeAtIndex(i)
}
}
}
print("wordArray :1\(wordArray)")
let count = wordArray.count
if count > 14 {
return
}
//建立不重复的含有15个字符的数组
for i in 0...(15-count-1) {
let index = arc4random()%UInt32(charArray.count)
wordArray.append(charArray[Int(index)])
}
print("wordArray :2\(wordArray)")
//进行乱序
var num = 15
while num > 0 {
let index = Int(arc4random()%UInt32(num))
print("\(index)")
let value = wordArray[index]
wordArray[index] = wordArray[num-1]
wordArray[num-1] = value
num -= 1
}
print("wordArray :3\(wordArray)")
}
使用
addkeyBoardView()
self.keyBoardView.doInitView(word)
func addkeyBoardView() {
keyBoardView.frame = seguesATableview.frame
keyBoardView.bottomBt.addTarget(self, action: #selector(nextQuestion), forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(keyBoardView)
}
1、继承UIView,自定义View,高内聚,低耦合的目的
class KeyBoardView: UIView
2、声明一些变量 ,全局变量,方便修改
var buttonWidth = 30.0
var buttonHeight = 30.0
var buttonSpace = 10.0
let labelWidth = 24
let labelHeight = 24
let labelSpace = 4
var charArray = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
var labelParentView = UIView()
let buttonsParentView = UIView()
var labelIndex = 0
var wordArray = [""]
var word = "monkey"
var spellText : Array! = [""]
3、添加显示的label
labelParentView.frame = CGRectMake(0, 20, SCREENWIDTH, CGFloat(labelHeight)+2)
self.addSubview(labelParentView)
if count%2 == 1 {
for i in 0...count-1 {
let viewLine = UIView.init(frame: CGRectMake(SCREENWIDTH/2 - CGFloat(labelWidth/2) - CGFloat((labelWidth + labelSpace )*((count-1)/2-i)), CGFloat(labelHeight), CGFloat(labelWidth), 2 ))
viewLine.backgroundColor = UIColor.greenColor()
viewLine.hidden = true
labelParentView.addSubview(viewLine)
let label = UILabel()
label.frame.origin.x = viewLine.frame.origin.x
label.frame.origin.y = viewLine.frame.origin.y - CGFloat(labelHeight) - 2
label.frame.size.width = CGFloat(labelWidth)
label.frame.size.height = CGFloat(labelHeight)
label.tag = i+100
label.textAlignment = NSTextAlignment.Center
label.text = "_"
label.textColor = colorFromHex("5eecff")
label.font = UIFont.systemFontOfSize(24)
labelParentView.addSubview(label)
if i == count-1 {
let button = UIButton(frame: CGRectMake(label.frame.origin.x+CGFloat(labelWidth+labelSpace*2),label.frame.origin.y,30,CGFloat(labelHeight)))
labelParentView.addSubview(button)
button.setImage(UIImage.init(named:"删除"), forState: UIControlState.Normal)
button.addTarget(self, action: #selector(deletechar), forControlEvents: UIControlEvents.TouchUpInside)
}
}
}else{
for i in 0...count-1 {
let viewLine = UIView.init(frame: CGRectMake(SCREENWIDTH/2 - CGFloat(labelSpace/2) - CGFloat(labelWidth * ((count)/2-i) ) - CGFloat(labelSpace*((count)/2-i-1)), CGFloat(labelHeight), CGFloat(labelWidth), 2 ))
viewLine.backgroundColor = UIColor.greenColor()
viewLine.hidden = true
labelParentView.addSubview(viewLine)
let label = UILabel()
label.frame.origin.x = viewLine.frame.origin.x
label.frame.origin.y = viewLine.frame.origin.y - CGFloat(labelHeight) - 2
label.frame.size.width = CGFloat(labelWidth)
label.frame.size.height = CGFloat(labelHeight)
label.tag = i+100
label.textAlignment = NSTextAlignment.Center
label.text = "_"
label.textColor = colorFromHex("5eecff")
label.font = UIFont.systemFontOfSize(24)
labelParentView.addSubview(label)
if i == count-1 {
let button = UIButton(frame: CGRectMake(label.frame.origin.x+CGFloat(labelWidth+labelSpace*2),label.frame.origin.y,30,CGFloat(labelHeight)))
labelParentView.addSubview(button)
button.setImage(UIImage.init(named:"删除"), forState: UIControlState.Normal)
button.addTarget(self, action: #selector(deletechar), forControlEvents: UIControlEvents.TouchUpInside)
}
}
}
4、添加键盘按钮
func randomKeyBoard(word:String) {
/**
* 4.0 + 5.0 * 3.5
* space个数 + button个数*相对比例
* @param SCREENWIDTH <#SCREENWIDTH description#>
*
* @return <#return value description#>
*/
buttonSpace = Double(14.0/375 * SCREENWIDTH)
print("buttonSpace -- \(buttonSpace)")
buttonWidth = Double(40.5/375 * SCREENWIDTH)
print("buttonWidth -- \(buttonWidth)")
buttonHeight = buttonWidth*9/8
putWordToStingArray(word)
var index = 0
buttonsParentView.frame = CGRectMake(0, CGRectGetMaxY(labelParentView.frame)+50, SCREENWIDTH , CGFloat(buttonHeight)*3+CGFloat(buttonSpace * 1.5)*2)
self.addSubview(buttonsParentView)
for i in 0...2{
for j in 0...4 {
print(i,j)
let button = UIButton.init(frame: CGRectMake(SCREENWIDTH/2 - CGFloat(buttonWidth/2) - CGFloat((buttonWidth + buttonSpace )*Double(2-j)), CGFloat(Double(i) * buttonHeight + Double(i) * buttonSpace * 1.5), CGFloat(buttonWidth), CGFloat(buttonHeight) ))
button.setTitle(wordArray[index], forState: UIControlState.Normal)
button.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Highlighted)
button.setBackgroundImage(self.imageWithColor(colorFromHex("aaf5ff")), forState: UIControlState.Normal)
button.setBackgroundImage(self.imageWithColor(colorFromHex("e4e4e4")), forState: UIControlState.Highlighted)
button.addTarget(self, action: #selector(addCharToLabel(_:)), forControlEvents: UIControlEvents.TouchUpInside)
button.layer.masksToBounds = true
button.layer.cornerRadius = 10
buttonsParentView.addSubview(button)
index += 1
}
}
}
5、按钮点击事件
func addCharToLabel(sender:UIButton) {
sender.setBackgroundImage(self.imageWithColor(colorFromHex("e4e4e4")), forState: UIControlState.Normal)
buttonArray.append(sender)
sender.userInteractionEnabled = false
let time = 1.2
if buttonArray.count == word.characters.count {
bottomBt.userInteractionEnabled = true
self.buttonsParentView.userInteractionEnabled = false
self.bottomBt.backgroundColor = colorFromHex("5eecff")
bottomBt.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
}
for view in labelParentView.subviews {
if view.tag == 100 + labelIndex {
let label = view as! UILabel
label.text = sender.titleForState(UIControlState.Normal)
labelIndex += 1
spellText.append(label.text!)
return
}
}
}
6、删除事件
func deletechar(sender: UIButton) {
if labelIndex > 0 {
labelIndex -= 1
}
self.buttonsParentView.userInteractionEnabled = true
self.buttonsParentView.backgroundColor = UIColor.clearColor()
if buttonArray.count>0 {
let button = buttonArray.last
button!.setBackgroundImage(self.imageWithColor(colorFromHex("aaf5ff")), forState: UIControlState.Normal)
button!.userInteractionEnabled = true
buttonArray.removeLast()
spellText.removeLast()
}
bottomBt.userInteractionEnabled = false
self.buttonsParentView.userInteractionEnabled = true
self.bottomBt.backgroundColor = UIColor.whiteColor()
bottomBt.setTitleColor(colorFromHex("5eecff"), forState: UIControlState.Normal)
for view in labelParentView.subviews {
if view.tag == 100 + labelIndex {
let label = view as! UILabel
label.text = "_"
return
}
}
}
第二种-可实现删除特定按钮
效果:
在调用界面使用两行代码:
self.addkeyBoardView()
self.keyBoardView.doInitView(word)
全部代码:
//
// KeyBoardView.swift
// 乱序键盘
//
// Created by fsk-0-1-n on 16/11/28.
// Copyright © 2016年 Xoxo. All rights reserved.
//
import UIKit
class KeyBoardView: UIView {
var buttonWidth = 30.0
var buttonHeight = 30.0
var buttonSpace = 10.0
let labelWidth = 24
let labelHeight = 25
let labelSpace = 4
var charArray = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
var labelParentView = UIView()
let buttonsParentView = UIView()
var wordArray = [""]
var word = "monkey"
var spellText : Array! = [""]
var relationLbWithBt = [UIButton:UILabel]()
var relationBtWithLb = [UILabel:UIButton]()
var lbArray = [UILabel]()
var btArray = [UIButton]()
var relationNum = 0
//传入分数面板的类型,用于控制标签的显示
override init(frame:CGRect)
{
super.init(frame:frame)
}
func doInitView(word:String) {
self.word = word
lbArray.removeAll()
btArray.removeAll()
relationNum = 0
addLabelAndView(word.characters.count)
randomKeyBoard(word)
addBottomButton()
}
let bottomBt = UIButton()
let SCREENWIDTH = UIScreen.mainScreen().bounds.size.width
func addBottomButton() {
bottomBt.frame = CGRectMake(SCREENWIDTH/7, CGRectGetMaxY(buttonsParentView.frame)+30, SCREENWIDTH*5/7 , SCREENWIDTH/7)
bottomBt.backgroundColor = UIColor.whiteColor()
bottomBt.layer.masksToBounds = true
bottomBt.layer.cornerRadius = SCREENWIDTH/7/2
bottomBt.layer.borderColor = colorFromHex("5eecff").CGColor
bottomBt.layer.borderWidth = 1.5
bottomBt.setTitle("确定", forState: UIControlState.Normal)
bottomBt.setTitleColor(colorFromHex("5eecff"), forState: UIControlState.Normal)
bottomBt.userInteractionEnabled = false
self.addSubview(bottomBt)
}
func judgeQuestion() -> (Bool) {
var text = ""
for (index,lb) in lbArray.enumerate(){
text = text + lb.text!
}
var judgeBool = true
if text == self.word {
judgeBool = true
}else{
judgeBool = false
}
for bt in self.buttonsParentView.subviews {
let bt1 = bt as! UIButton
bt1.backgroundColor = colorFromHex("e4e4e4")
}
for (index,lb) in lbArray.enumerate(){
let bt = relationBtWithLb[lb]!
if judgeBool == true {
bt.backgroundColor = colorFromHex("b4e9ac")
self.bottomBt.backgroundColor = colorFromHex("8cdc7f")
self.bottomBt.layer.borderColor = colorFromHex("8cdc7f").CGColor
}else{
bt.backgroundColor = colorFromHex("ff877f")
self.bottomBt.backgroundColor = colorFromHex("ff877f")
self.bottomBt.layer.borderColor = colorFromHex("ff877f").CGColor
}
}
return judgeBool
}
func randomKeyBoard(word:String) {
/**
* 4.0 + 5.0 * 3.5
* space个数 + button个数*相对比例
* @param SCREENWIDTH <#SCREENWIDTH description#>
*
*/
buttonSpace = Double(14.0/375 * SCREENWIDTH)
buttonWidth = Double(40.5/375 * SCREENWIDTH)
buttonHeight = buttonWidth*9/8
putWordToStingArray(word)
var index = 0
buttonsParentView.frame = CGRectMake(0, CGRectGetMaxY(labelParentView.frame)+50, SCREENWIDTH , CGFloat(buttonHeight)*3+CGFloat(buttonSpace * 1.5)*2)
self.addSubview(buttonsParentView)
btArray.removeAll()
for i in 0...2{
for j in 0...4 {
let button = UIButton.init(frame: CGRectMake(SCREENWIDTH/2 - CGFloat(buttonWidth/2) - CGFloat((buttonWidth + buttonSpace )*Double(2-j)), CGFloat(Double(i) * buttonHeight + Double(i) * buttonSpace * 1.5), CGFloat(buttonWidth), CGFloat(buttonHeight) ))
button.setTitle(wordArray[index], forState: UIControlState.Normal)
button.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Highlighted)
button.backgroundColor = colorFromHex("aaf5ff")
button.addTarget(self, action: #selector(addCharToLabel(_:)), forControlEvents: UIControlEvents.TouchUpInside)
button.layer.masksToBounds = true
button.layer.cornerRadius = 10
buttonsParentView.addSubview(button)
index += 1
btArray.append(button)
}
}
}
func addLabelAndView(count:Int) {
labelParentView.frame = CGRectMake(0, 20, SCREENWIDTH, CGFloat(labelHeight)+2)
self.addSubview(labelParentView)
lbArray.removeAll()
if count%2 == 1 {
for i in 0...count-1 {
let viewLine = UIView.init(frame: CGRectMake(SCREENWIDTH/2 - CGFloat(labelWidth/2) - CGFloat((labelWidth + labelSpace )*((count-1)/2-i)), CGFloat(labelHeight), CGFloat(labelWidth), 2 ))
viewLine.backgroundColor = UIColor.greenColor()
viewLine.hidden = true
labelParentView.addSubview(viewLine)
let label = UILabel()
label.frame.origin.x = viewLine.frame.origin.x
label.frame.origin.y = viewLine.frame.origin.y - CGFloat(labelHeight) - 2
label.frame.size.width = CGFloat(labelWidth)
label.frame.size.height = CGFloat(labelHeight)
label.textAlignment = NSTextAlignment.Center
label.text = "_"
label.textColor = colorFromHex("5eecff")
label.font = UIFont.systemFontOfSize(22)
labelParentView.addSubview(label)
if i == count-1 {
let button = UIButton(frame: CGRectMake(label.frame.origin.x+CGFloat(labelWidth+labelSpace*2),label.frame.origin.y,30,CGFloat(labelHeight)))
labelParentView.addSubview(button)
button.setImage(UIImage.init(named:"删除"), forState: UIControlState.Normal)
button.addTarget(self, action: #selector(deletechar), forControlEvents: UIControlEvents.TouchUpInside)
}
lbArray.append(label)
}
}else{
for i in 0...count-1 {
let viewLine = UIView.init(frame: CGRectMake(SCREENWIDTH/2 - CGFloat(labelSpace/2) - CGFloat(labelWidth * ((count)/2-i) ) - CGFloat(labelSpace*((count)/2-i-1)), CGFloat(labelHeight), CGFloat(labelWidth), 2 ))
viewLine.backgroundColor = UIColor.greenColor()
viewLine.hidden = true
labelParentView.addSubview(viewLine)
let label = UILabel()
label.frame.origin.x = viewLine.frame.origin.x
label.frame.origin.y = viewLine.frame.origin.y - CGFloat(labelHeight) - 2
label.frame.size.width = CGFloat(labelWidth)
label.frame.size.height = CGFloat(labelHeight)
label.textAlignment = NSTextAlignment.Center
label.text = "_"
label.textColor = colorFromHex("5eecff")
label.font = UIFont.systemFontOfSize(24)
labelParentView.addSubview(label)
if i == count-1 {
let button = UIButton(frame: CGRectMake(label.frame.origin.x+CGFloat(labelWidth+labelSpace*2),label.frame.origin.y,30,CGFloat(labelHeight)))
labelParentView.addSubview(button)
button.setImage(UIImage.init(named:"删除"), forState: UIControlState.Normal)
button.addTarget(self, action: #selector(deletechar), forControlEvents: UIControlEvents.TouchUpInside)
}
lbArray.append(label)
}
}
}
func deletechar(sender: UIButton) {
if lbArray.count < 1 {
return
}
if relationNum == self.word.characters.count {
let bt = relationBtWithLb[lbArray.last!]!
let lb = lbArray.last!
print("111 \(bt)")
print("222 \(lb)")
cancleRelation(bt, lb: lb)
changUIAccordingType(2, bt: bt, lb: lb)
return
}
for (index,lb) in lbArray.enumerate(){
if relationBtWithLb[lb] == nil {
let bt = relationBtWithLb[lbArray[index-1]]!
let lb = lbArray[index-1]
cancleRelation(bt, lb: lb)
changUIAccordingType(2, bt: bt, lb: lb)
return
}
}
}
var buttonArray = [UIButton]()
func cancleRelation(bt:UIButton,lb:UILabel) {
relationBtWithLb[lb] = nil
relationLbWithBt[bt] = nil
if relationNum > 0 {
relationNum -= 1
}
}
func doRelation(bt:UIButton,lb:UILabel) {
//1改变颜色
//2改变显示
//3设置bt对应的lb,将lb对应的bt
relationBtWithLb[lb] = bt
relationLbWithBt[bt] = lb
relationNum += 1
}
func changUIAccordingType(type:Int,bt:UIButton,lb:UILabel) {
//type:1 选中 type:2 取消
switch type {
case 1:
bt.backgroundColor = colorFromHex("e4e4e4")
lb.text = bt.titleForState(UIControlState.Normal)
if relationNum == word.characters.count {
bottomBt.userInteractionEnabled = true
self.bottomBt.backgroundColor = colorFromHex("5eecff")
bottomBt.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
for bt in self.buttonsParentView.subviews {
let bt1 = bt as! UIButton
bt1.backgroundColor = colorFromHex("e4e4e4")
}
for (index,lb) in lbArray.enumerate(){
let bt = relationBtWithLb[lb]!
bt.backgroundColor = colorFromHex("aaf5ff")
}
}
break
case 2:
bt.backgroundColor = colorFromHex("aaf5ff")
lb.text = "_"
if relationNum + 1 == self.word.characters.count {
for bt in self.buttonsParentView.subviews {
let bt1 = bt as! UIButton
bt1.backgroundColor = colorFromHex("aaf5ff")
}
for (index,lb) in lbArray.enumerate(){
let bt = relationBtWithLb[lb]
if bt == nil {
}else{
bt!.backgroundColor = colorFromHex("e4e4e4")
}
}
}
break
default:
break
}
}
func addCharToLabel(sender:UIButton) {
//找到lb对应为空的button
for (index,lb) in lbArray.enumerate() {
//如果lb对应的button状态为空
if relationBtWithLb[lb] == nil {
//判断button的选中状态
if relationBtWithLb[lb] == nil{
//如果同时button对应的lb为空,说明应该可以建立新的联系
doRelation(sender, lb: lb)
//改变UI
changUIAccordingType(1, bt: sender, lb: lb)
}else{
//说明button已经被选中,说明要取消之前该button建立的联系
cancleRelation(sender, lb: lb)
//改变UI
changUIAccordingType(2, bt: sender, lb: lb)
}
//确保一次建立一个联系,或取消一个联系
break
}else{
//判断button的选中状态
if relationBtWithLb[lb] == sender{
//说明button已经被选中,说明要取消之前该button建立的联系
cancleRelation(sender, lb: lb)
//改变UI
changUIAccordingType(2, bt: sender, lb: lb)
//确保一次建立一个联系,或取消一个联系
break
}
}
}
}
func putWordToStingArray(word:String) {
wordArray.removeAll()
for char in word.characters {
wordArray.append("\(char)")
for (i,item) in charArray.enumerate() {
if "\(char)" == item {
charArray.removeAtIndex(i)
}
}
}
let count = wordArray.count
if count > 14 {
return
}
//建立不重复的含有15个字符的数组
for i in 0...(15-count-1) {
let index = arc4random()%UInt32(charArray.count)
wordArray.append(charArray[Int(index)])
}
//进行乱序
var num = 15
while num > 0 {
let index = Int(arc4random()%UInt32(num))
let value = wordArray[index]
wordArray[index] = wordArray[num-1]
wordArray[num-1] = value
num -= 1
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}