Reputation: 669
I am trying to make a custom jump bar which can be attached to UITableView.
What I want to achieve now is if user touches A and slides through Z, I want print out A, B, C, D..., Z. Currently, it only prints A, A, A...A. Is there anyway I can achieve it?
Each letter is UIButton subview of UIView.
class TableViewJumpBar{
let tableView: UITableView
let view: UIView
let jumpBar: UIView!
private var jumpIndexes: [Character]
init(tableView: UITableView, view: UIView){
self.view = view
self.tableView = tableView
jumpBar = UIView(frame: .zero)
jumpBar.backgroundColor = UIColor.gray
let aScalars = "A".unicodeScalars
let aCode = aScalars[aScalars.startIndex].value
jumpIndexes = (0..<26).map {
i in Character(UnicodeScalar(aCode + i)!)
}
}
func setFrame(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat){
guard jumpIndexes.count > 0 else{
print("Jump indexes cannot be empty")
return
}
//Remove jumpbar and remove all subviews
jumpBar.removeFromSuperview()
for subView in jumpBar.subviews{
subView.removeFromSuperview()
}
jumpBar.frame = CGRect(x: x, y: y, width: width, height: height)
let height = height/CGFloat(jumpIndexes.count)
for i in 0..<jumpIndexes.count{
let indexButton = UIButton(frame: CGRect(x:CGFloat(0.0), y: CGFloat(i)*height, width: width, height: height))
indexButton.setTitle(String(jumpIndexes[i]), for: .normal)
indexButton.addTarget(self, action: #selector(jumpIndexButtonTouched(_:)), for: .allEvents)
jumpBar.addSubview(indexButton)
}
self.view.addSubview(jumpBar)
}
///Touch has been begun
@objc private func jumpIndexButtonTouched(_ sender: UIButton!){
print(sender.titleLabel?.text)
}
Upvotes: 1
Views: 371
Reputation: 172
this code works and print start and finish characters.
class ViewController: UIViewController {
@IBOutlet weak var myTableView: UITableView!
@IBOutlet weak var myView: UIView!
var startChar = ""
var finishChar = ""
override func viewDidLoad() {
super.viewDidLoad()
let table = TableViewJumpBar(tableView: myTableView, view: myView)
table.setFrame(x: 0, y: 0, width: 100, height: self.view.frame.size.height)
print(myView.subviews[0].subviews)
setPanGesture()
}
func setPanGesture() {
let pan = UIPanGestureRecognizer(target: self, action: #selector(panRecognized))
self.myView.addGestureRecognizer(pan)
}
@objc func panRecognized(sender: UIPanGestureRecognizer) {
let location = sender.location(in: myView)
if sender.state == .began {
for button in myView.subviews[0].subviews {
if let button = button as? UIButton, button.frame.contains(location), let startCharacter = button.titleLabel?.text {
self.startChar = startCharacter
}
}
} else if sender.state == .ended {
for button in myView.subviews[0].subviews {
if let button = button as? UIButton, button.frame.contains(location), let finishCharacter = button.titleLabel?.text {
self.finishChar = finishCharacter
}
}
print("start with \(startChar), finish with \(finishChar)")
}
}
}
In your code I delete Button action. you can use labels instead Buttons.
class TableViewJumpBar {
let tableView: UITableView
let view: UIView
let jumpBar: UIView!
private var jumpIndexes: [Character]
init(tableView: UITableView, view: UIView){
self.view = view
self.tableView = tableView
jumpBar = UIView(frame: .zero)
jumpBar.backgroundColor = UIColor.gray
let aScalars = "A".unicodeScalars
let aCode = aScalars[aScalars.startIndex].value
jumpIndexes = (0..<26).map {
i in Character(UnicodeScalar(aCode + i)!)
}
}
func setFrame(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat){
guard jumpIndexes.count > 0 else{
print("Jump indexes cannot be empty")
return
}
jumpBar.removeFromSuperview()
for subView in jumpBar.subviews{
subView.removeFromSuperview()
}
jumpBar.frame = CGRect(x: x, y: y, width: width, height: height)
let height = height/CGFloat(jumpIndexes.count)
for i in 0..<jumpIndexes.count{
let indexButton = UIButton(frame: CGRect(x:CGFloat(0.0), y: CGFloat(i)*height, width: width, height: height))
indexButton.setTitle(String(jumpIndexes[i]), for: .normal)
jumpBar.addSubview(indexButton)
}
self.view.addSubview(jumpBar)
}
}
Upvotes: 2