diff --git a/README.md b/README.md index 4ac6496..a1d06f2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ MPGTextField ========= +Modified this project for this question: [Swift MPGTextField autocomplete in tableview cell](http://stackoverflow.com/q/33692207/1378447) +

An autocomplete textfield for iOS which provides suggestions as you type. The textfield can be configured to ensure that a selection is compulsorily made from the list of suggestions and gives you control over the size of the popover showing suggestions based on the text entered by the user. diff --git a/Swift/MPGTextField-Swift/MPGTextField-Swift.xcodeproj/project.pbxproj b/Swift/MPGTextField-Swift/MPGTextField-Swift.xcodeproj/project.pbxproj index 3f6abb3..3eb0af4 100644 --- a/Swift/MPGTextField-Swift/MPGTextField-Swift.xcodeproj/project.pbxproj +++ b/Swift/MPGTextField-Swift/MPGTextField-Swift.xcodeproj/project.pbxproj @@ -159,6 +159,8 @@ 0ACD2D491944D84D005AF774 /* Project object */ = { isa = PBXProject; attributes = { + LastSwiftMigration = 0710; + LastSwiftUpdateCheck = 0710; LastUpgradeCheck = 0600; ORGANIZATIONNAME = Mappgic; TargetAttributes = { diff --git a/Swift/MPGTextField-Swift/MPGTextField-Swift/AppDelegate.swift b/Swift/MPGTextField-Swift/MPGTextField-Swift/AppDelegate.swift index 8f32fcf..6285005 100644 --- a/Swift/MPGTextField-Swift/MPGTextField-Swift/AppDelegate.swift +++ b/Swift/MPGTextField-Swift/MPGTextField-Swift/AppDelegate.swift @@ -13,10 +13,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { + func applicationDidFinishLaunching(application: UIApplication) { // Override point for customization after application launch. - return true } func applicationWillResignActive(application: UIApplication) { diff --git a/Swift/MPGTextField-Swift/MPGTextField-Swift/Base.lproj/Main.storyboard b/Swift/MPGTextField-Swift/MPGTextField-Swift/Base.lproj/Main.storyboard index af44317..9d3568c 100644 --- a/Swift/MPGTextField-Swift/MPGTextField-Swift/Base.lproj/Main.storyboard +++ b/Swift/MPGTextField-Swift/MPGTextField-Swift/Base.lproj/Main.storyboard @@ -1,7 +1,8 @@ - + - + + @@ -13,7 +14,7 @@ - + @@ -36,6 +37,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + - @@ -123,7 +148,7 @@ - + diff --git a/Swift/MPGTextField-Swift/MPGTextField-Swift/ViewController.swift b/Swift/MPGTextField-Swift/MPGTextField-Swift/ViewController.swift index b4bbf4e..590a364 100644 --- a/Swift/MPGTextField-Swift/MPGTextField-Swift/ViewController.swift +++ b/Swift/MPGTextField-Swift/MPGTextField-Swift/ViewController.swift @@ -10,14 +10,14 @@ import UIKit class ViewController: UIViewController, MPGTextFieldDelegate { - var sampleData = Dictionary[]() - @IBOutlet var name : MPGTextField_Swift + var sampleData = [Dictionary]() + @IBOutlet var name : MPGTextField_Swift? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. self.generateData() - name.mDelegate = self + name!.mDelegate = self } override func didReceiveMemoryWarning() { @@ -26,24 +26,24 @@ class ViewController: UIViewController, MPGTextFieldDelegate { } func generateData(){ - var err : NSErrorPointer? - var dataPath = NSBundle.mainBundle().pathForResource("sample_data", ofType: "json") - var data = NSData.dataWithContentsOfFile(dataPath, options: NSDataReadingOptions.DataReadingUncached, error: err!) - var contents : AnyObject[]! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: err!) as AnyObject[] + //var err : NSErrorPointer? + let dataPath = NSBundle.mainBundle().pathForResource("sample_data", ofType: "json") + let data = try? NSData(contentsOfFile: dataPath!, options: .DataReadingUncached) + var contents : [AnyObject]! = try? NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as! [AnyObject] //println(contents[0]["first_name"]) for var i = 0;i Dictionary[] + func dataForPopoverInTextField(textfield: MPGTextField_Swift) -> [Dictionary] { return sampleData } @@ -53,7 +53,22 @@ class ViewController: UIViewController, MPGTextFieldDelegate { } func textFieldDidEndEditing(textField: MPGTextField_Swift, withSelection data: Dictionary){ - println("Dictionary received = \(data)") + print("Dictionary received = \(data)") + } +} + +extension ViewController : UITableViewDataSource { + + func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 10; + } + + func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) + let mpgTextField = cell.viewWithTag(420) as! MPGTextField_Swift + mpgTextField.mDelegate = self; + + return cell } } diff --git a/Swift/MPGTextField/MPGTextField-Swift.swift b/Swift/MPGTextField/MPGTextField-Swift.swift index 26580c1..14f9b1d 100644 --- a/Swift/MPGTextField/MPGTextField-Swift.swift +++ b/Swift/MPGTextField/MPGTextField-Swift.swift @@ -9,17 +9,17 @@ import UIKit @objc protocol MPGTextFieldDelegate{ - func dataForPopoverInTextField(textfield: MPGTextField_Swift) -> Dictionary[] + func dataForPopoverInTextField(textfield: MPGTextField_Swift) -> [Dictionary] - @optional func textFieldDidEndEditing(textField: MPGTextField_Swift, withSelection data: Dictionary) - @optional func textFieldShouldSelect(textField: MPGTextField_Swift) -> Bool + optional func textFieldDidEndEditing(textField: MPGTextField_Swift, withSelection data: Dictionary) + optional func textFieldShouldSelect(textField: MPGTextField_Swift) -> Bool } class MPGTextField_Swift: UITextField, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource, UIGestureRecognizerDelegate { var mDelegate : MPGTextFieldDelegate? var tableViewController : UITableViewController? - var data = Dictionary[]() + var data = [Dictionary]() //Set this to override the default color of suggestions popover. The default color is [UIColor colorWithWhite:0.8 alpha:0.9] @IBInspectable var popoverBackgroundColor : UIColor = UIColor(red: 240.0/255.0, green: 240.0/255.0, blue: 240.0/255.0, alpha: 1.0) @@ -31,14 +31,15 @@ class MPGTextField_Swift: UITextField, UITextFieldDelegate, UITableViewDelegate, @IBInspectable var seperatorColor : UIColor = UIColor(white: 0.95, alpha: 1.0) - init(frame: CGRect) { + override init(frame: CGRect) { super.init(frame: frame) // Initialization code } - init(coder aDecoder: NSCoder!){ + required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } + /* // Only override drawRect: if you perform custom drawing. @@ -51,16 +52,16 @@ class MPGTextField_Swift: UITextField, UITextFieldDelegate, UITableViewDelegate, override func layoutSubviews(){ super.layoutSubviews() - let str : String = self.text + let str : String = self.text! - if (countElements(str) > 0) && (self.isFirstResponder()) + if (str.characters.count > 0) && (self.isFirstResponder()) { - if mDelegate{ + if (mDelegate != nil){ data = mDelegate!.dataForPopoverInTextField(self) self.provideSuggestions() } else{ - println(" WARNING: You have not implemented the requred methods of the MPGTextField protocol.") + print(" WARNING: You have not implemented the requred methods of the MPGTextField protocol.") } } else{ @@ -74,6 +75,11 @@ class MPGTextField_Swift: UITextField, UITextFieldDelegate, UITableViewDelegate, } override func resignFirstResponder() -> Bool{ + + guard let _ = tableViewController else { + return super.resignFirstResponder() + } + UIView.animateWithDuration(0.3, animations: ({ self.tableViewController!.tableView.alpha = 0.0 @@ -88,18 +94,18 @@ class MPGTextField_Swift: UITextField, UITextFieldDelegate, UITableViewDelegate, } func provideSuggestions(){ - if let tvc = self.tableViewController { + if let _ = self.tableViewController { tableViewController!.tableView.reloadData() } - else if self.applyFilterWithSearchQuery(self.text).count > 0{ + else if self.applyFilterWithSearchQuery(self.text!).count > 0{ //Add a tap gesture recogniser to dismiss the suggestions view when the user taps outside the suggestions view let tapRecognizer = UITapGestureRecognizer(target: self, action: "tapped:") tapRecognizer.numberOfTapsRequired = 1 tapRecognizer.cancelsTouchesInView = false tapRecognizer.delegate = self - self.superview.addGestureRecognizer(tapRecognizer) + self.superview!.addGestureRecognizer(tapRecognizer) - self.tableViewController = UITableViewController.alloc() + self.tableViewController = UITableViewController() self.tableViewController!.tableView.delegate = self self.tableViewController!.tableView.dataSource = self self.tableViewController!.tableView.backgroundColor = self.popoverBackgroundColor @@ -120,7 +126,20 @@ class MPGTextField_Swift: UITextField, UITextFieldDelegate, UITableViewDelegate, frameForPresentation.size.height = 200; tableViewController!.tableView.frame = frameForPresentation - self.superview.addSubview(tableViewController!.tableView) + //BUG FIX - SHOW ON TOP + + //self.superview!.addSubview(tableViewController!.tableView) + + let aView = tableViewController!.tableView + var frame = aView.frame + + frame.origin = self.superview!.convertPoint(frame.origin, toView: nil) + aView.frame = frame + + self.window!.addSubview(aView) + + //// + self.tableViewController!.tableView.alpha = 0.0 UIView.animateWithDuration(0.3, animations: ({ @@ -142,8 +161,8 @@ class MPGTextField_Swift: UITextField, UITextFieldDelegate, UITableViewDelegate, } } - func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int{ - var count = self.applyFilterWithSearchQuery(self.text).count + func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ + let count = self.applyFilterWithSearchQuery(self.text!).count if count == 0{ UIView.animateWithDuration(0.3, animations: ({ @@ -161,38 +180,38 @@ class MPGTextField_Swift: UITextField, UITextFieldDelegate, UITableViewDelegate, } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { - var cell = tableView.dequeueReusableCellWithIdentifier("MPGResultsCell") as? UITableViewCell + var cell = tableView.dequeueReusableCellWithIdentifier("MPGResultsCell") - if !cell{ + if (cell == nil){ cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "MPGResultsCell") } cell!.backgroundColor = UIColor.clearColor() - let dataForRowAtIndexPath = self.applyFilterWithSearchQuery(self.text)[indexPath.row] + let dataForRowAtIndexPath = self.applyFilterWithSearchQuery(self.text!)[indexPath.row] let displayText : AnyObject? = dataForRowAtIndexPath["DisplayText"] let displaySubText : AnyObject? = dataForRowAtIndexPath["DisplaySubText"] - cell!.textLabel.text = displayText as String - cell!.detailTextLabel.text = displaySubText as String + cell!.textLabel!.text = displayText as? String + cell!.detailTextLabel!.text = displaySubText as? String return cell! } - func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!){ - //self.text = self.applyFilterWithSearchQuery(self.text)[indexPath.row]["DisplayText"] + func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){ + self.text = self.applyFilterWithSearchQuery(self.text!)[indexPath.row]["DisplayText"] as? String self.resignFirstResponder() } // #pragma mark Filter Method - func applyFilterWithSearchQuery(filter : String) -> Dictionary[] + func applyFilterWithSearchQuery(filter : String) -> [Dictionary] { //let predicate = NSPredicate(format: "DisplayText BEGINSWITH[cd] \(filter)") - var lower = (filter as NSString).lowercaseString - var filteredData = data.filter({ + _ = (filter as NSString).lowercaseString + let filteredData = data.filter({ if let match : AnyObject = $0["DisplayText"]{ //println("LCS = \(filter.lowercaseString)") - return (match as NSString).lowercaseString.hasPrefix((filter as NSString).lowercaseString) + return (match as! NSString).lowercaseString.hasPrefix((filter as NSString).lowercaseString) } else{ return false @@ -205,15 +224,15 @@ class MPGTextField_Swift: UITextField, UITextFieldDelegate, UITableViewDelegate, if let table = self.tableViewController{ table.tableView.removeFromSuperview() } - if mDelegate?.textFieldShouldSelect?(self){ - if self.applyFilterWithSearchQuery(self.text).count > 0 { - let selectedData = self.applyFilterWithSearchQuery(self.text)[0] + if ((mDelegate?.textFieldShouldSelect?(self)) != nil){ + if self.applyFilterWithSearchQuery(self.text!).count > 0 { + let selectedData = self.applyFilterWithSearchQuery(self.text!)[0] let displayText : AnyObject? = selectedData["DisplayText"] - self.text = displayText as String + self.text = displayText as? String mDelegate?.textFieldDidEndEditing?(self, withSelection: selectedData) } else{ - mDelegate?.textFieldDidEndEditing?(self, withSelection: ["DisplayText":self.text, "CustomObject":"NEW"]) + mDelegate?.textFieldDidEndEditing?(self, withSelection: ["DisplayText":self.text!, "CustomObject":"NEW"]) } }