Dismiss UITableView Cell upon selection in Swift? - ios

I have a UITableView Cell in a View Controller serving as a display for autocompletion for a text field. However, selecting one of the autocomplete suggestions does not dismiss the table view cell. I have tried "self.dismissViewControllerAnimated(True, completion: nil)" inside my didSelectRowAtIndexPath function for UITableView. Any thoughts?
class ViewController: UIViewController, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var RecName: UITextField!
#IBOutlet var Body: UITextField!
#IBOutlet var RecEmail: UITextField!
var emailArray = ""
var emailNSArray = [""]
var autocomplete = [String]()
var tycard2 = ""
var addressBook: ABAddressBookRef?
#IBOutlet var autocompleteTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
//email
RecEmail.delegate = self
//autocomplete
autocompleteTableView!.delegate = self
autocompleteTableView!.dataSource = self
autocompleteTableView!.scrollEnabled = true
autocompleteTableView!.hidden = true
println(tycard2)
}
func createAddressBook(){
var error: Unmanaged<CFError>?
addressBook = ABAddressBookCreateWithOptions(nil, &error).takeRetainedValue()
}
func textToImage(drawText: NSString, inImage: UIImage, atPoint:CGPoint)->UIImage{
// Setup the font specific variables
var textColor: UIColor = UIColor.whiteColor()
var textFont: UIFont = UIFont(name: "Helvetica Bold", size: 20)!
//Setup the image context using the passed image.
UIGraphicsBeginImageContext(inImage.size)
//Setups up the font attributes that will be later used to dictate how the text should be drawn
let textFontAttributes = [
NSFontAttributeName: textFont,
NSForegroundColorAttributeName: textColor,
]
//Put the image into a rectangle as large as the original image.
inImage.drawInRect(CGRectMake(0, 0, inImage.size.width, inImage.size.height))
// Creating a point within the space that is as bit as the image.
var rect: CGRect = CGRectMake(atPoint.x, atPoint.y, inImage.size.width, inImage.size.height)
//Now Draw the text into an image.
drawText.drawInRect(rect, withAttributes: textFontAttributes)
// Create a new image out of the images we have created
var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
// End the context now that we have the image we need
UIGraphicsEndImageContext()
//And pass it back up to the caller.
return newImage
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
autocompleteTableView!.hidden = false
var substring = (self.RecEmail.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
searchAutocompleteEntriesWithSubstring(substring)
self.dismissViewControllerAnimated(true, completion: {})
return true
}
func searchAutocompleteEntriesWithSubstring(substring: String)
{
autocomplete.removeAll(keepCapacity: false)
let delegate = UIApplication.sharedApplication().delegate as! AppDelegate
let emailArray = delegate.emailArray
var emailNSArray = emailArray.componentsSeparatedByString(",")
for curString in emailNSArray
{
println(curString)
var myString: NSString! = curString as NSString
var substringRange: NSRange! = myString.rangeOfString(substring)
if (substringRange.location == 0)
{
autocomplete.append(curString)
}
}
autocompleteTableView!.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return autocomplete.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let autoCompleteRowIdentifier = "AutoCompleteRowIdentifier"
var cell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier) as? UITableViewCell
if let tempo1 = cell
{
let index = indexPath.row as Int
cell!.textLabel!.text = autocomplete[index]
} else
{
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: autoCompleteRowIdentifier)
}
return cell!
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedCell : UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
self.dismissViewControllerAnimated(true, completion: nil)
println("dismiss")
RecEmail.text = selectedCell.textLabel!.text
}
Thanks!

You are trying to dismiss a ViewController not a table view cell. If you want to remove a cell, just delete current row index in your data source (here to be your [String] array autocomplete), and do reload data.

Related

Swift 1/2 TextField tag display all names

I have a text field that, when you type a name, should show a suggested name that get I from an array with JSON, the problem is that it shows only one name. For example if I type Tom it shows only Tom Cruise and not Tommy Gien. How can I resolve that?
CODE:
class ViewController: UIViewController, UITextViewDelegate, UITextFieldDelegate,UITableViewDataSource, UITableViewDelegate {
let save = NSUserDefaults.standardUserDefaults()
#IBOutlet var amountPoints: UILabel!
#IBOutlet var reasonView: UITextView!
#IBOutlet var toField: UITextField!
#IBOutlet var pointsField: UITextField!
#IBOutlet var autocompleteTableView: UITableView!
var pastUrls: [String] = []
var autocompleteUrls = [String]()
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
toField.delegate = self
reasonView.layer.cornerRadius = 1
reasonView.layer.borderWidth = 0.7
reasonView.layer.borderColor = UIColor.grayColor().CGColor
autocompleteTableView.delegate = self
autocompleteTableView.dataSource = self
autocompleteTableView.scrollEnabled = true
autocompleteTableView.hidden = true
getallUser()
var Names = save.arrayForKey("give.Name")
pastUrls = Names as! [String]
print(pastUrls)
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
{
autocompleteTableView.hidden = false
let substring = (textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
searchAutocompleteEntriesWithSubstring(substring)
return true // not sure about this - could be false
}
func searchAutocompleteEntriesWithSubstring(substring: String)
{
autocompleteUrls.removeAll(keepCapacity: false)
for curString in pastUrls
{
let myString:NSString! = curString as NSString
let substringRange :NSRange! = myString.rangeOfString(substring)
if (substringRange.location == 0)
{
autocompleteUrls.append(curString)
}
}
autocompleteTableView.reloadData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return autocompleteUrls.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let autoCompleteRowIdentifier = "AutoCompleteRowIdentifier"
let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier, forIndexPath: indexPath) as UITableViewCell
let index = indexPath.row as Int
cell.textLabel!.text = autocompleteUrls[index]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedCell : UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
toField.text = selectedCell.textLabel!.text
autocompleteTableView.hidden = true
}
func textViewDidBeginEditing(textView: UITextView) {
reasonView.text = ""
}
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "\n"
{
textView.resignFirstResponder()
return false
}
return true
}
#IBAction func giveButton(sender: UIButton) {
}
#IBAction func returnButton(sender: UIBarButtonItem) {
self.dismissViewControllerAnimated(true, completion: nil)
}
Try replacing your method in seachAutocompleteEntriesWithSubtring with the following
func searchAutocompleteEntriesWithSubstring(substring: String)
{
autocompleteUrls.removeAll(keepCapacity: false)
for curString in pastUrls
{
var myString:NSString! = curString as NSString
var substringRange :NSRange! = myString.rangeOfString(substring)
if (substringRange.location == 0)
{
autocompleteUrls.append(curString)
}
}
autocompleteTableView.reloadData()
}

How to make dynamic height of UITableViewCell

I would like to create dynamic height of UITableViewCell depending tablecell content.
But i couldn't.
import UIKit
class WorkItemCell: UITableViewCell{
#IBOutlet weak var item_view: UIView!
#IBOutlet weak var minimum_startday_label: CustomLabel!
#IBOutlet weak var catchcopyLabel: CustomLabel!
#IBOutlet weak var stationLabel: UILabel!
#IBOutlet weak var paymentLabel: UILabel!
#IBOutlet weak var limitLabel: UILabel!
#IBOutlet weak var mainjobLabel: UILabel!
#IBOutlet weak var companyLabel: UILabel!
#IBOutlet weak var workstartdateLabel2: UILabel!
#IBOutlet weak var fav_view: ImageWithView!
#IBOutlet weak var img_seen_view: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
//self.fav_view = ImageWithView.instance()
self.fav_view.checkedImage = UIImage(named: "fav_on")
self.fav_view.uncheckedImage = UIImage(named: "fav_off")
}
override func layoutSubviews() {
super.layoutSubviews()
self.contentView.layoutIfNeeded()
self.catchcopyLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.catchcopyLabel.bounds)
}
private var _workdic: NSDictionary?
var workdic: NSDictionary? {
get {
return _workdic
}
set(workdic) {
_workdic = workdic
if let workdic = workdic {
let workplace = workdic["WorkPlace"] as? String
let companyname = workdic["CompanyName"] as? String
let jobname = workdic["JobName"] as? String
let payment = workdic["Payment"] as? String
let workstartdate = workdic["WorkStartDate"] as? String
let workdatetime = workdic["WorkDateTime"] as? String
let minimumday = workdic["MinimumWorkDay"] as? String
let applyenddate = workdic["ApplyEndDate"] as? String
let catchcopy = workdic["CatchCopy"] as? String
if notnullCheck(catchcopy){
//行間
let attributedText = NSMutableAttributedString(string: catchcopy!)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 5
paragraphStyle.lineBreakMode = NSLineBreakMode.ByTruncatingTail
attributedText.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, attributedText.length))
self.catchcopyLabel.attributedText = attributedText
}
self.catchcopyLabel.sizeToFit()
if let payment_constant = payment{
self.paymentLabel.text = payment_constant
}
if notnullCheck(minimumday) && notnullCheck(workstartdate){
self.minimum_startday_label.text = minimumday!+" "+workstartdate!
}else{
self.minimum_startday_label.text = ""
}
if let applyenddate_constant = applyenddate{
self.limitLabel.text = applyenddate_constant
}
if let jobname_constant = jobname{
self.mainjobLabel.text = jobname_constant
}
if let workdatetime_constant = workdatetime{
self.workstartdateLabel2.text = workdatetime_constant
}
if let companyname_constant = companyname{
self.companyLabel.text = companyname_constant
}
self.stationLabel.text = workplace
self.item_view.sizeToFit()
}
}
}
class func heightForRow(tableView: UITableView, workdic: NSDictionary?) -> CGFloat {
struct Sizing {
static var cell: WorkItemCell?
}
if Sizing.cell == nil {
Sizing.cell = tableView.dequeueReusableCellWithIdentifier("WorkItemCell") as? WorkItemCell
}
if let cell = Sizing.cell {
cell.frame.size.width = CGRectGetWidth(tableView.bounds)
cell.workdic = workdic
cell.setNeedsDisplay()
cell.layoutIfNeeded()
let size = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
print(size)
return size.height+1
}
return 0
}
}
Above code has item_view.
It has all label and image.
It is setted margin at 4 points(top,left,bottom,right),5px.
I use above cell for data list.
It has around 5000 counts.
Catch copy label is often setted 2 line sentence.
I want to change item_view height and cell height each catch_copy_label's height.
But I couldn't.
I always have gotten same height,26px.
(366.5, 26.0)
(366.5, 26.0)
What should i do?
I have add the part of view controller's source.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat{
if self.int_total == 0{
return self.view.frame.size.height
}else{
if let workdic: AnyObject = workdata.safeObjectAtIndex(indexPath.row){
return WorkItemCell.heightForRow(self.workview, workdic: (workdic as! NSDictionary),base_height:170)
}else{
return 199
}
}
}
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 199
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.int_total == 0{
return 1
}
return self.workdata.count
}
/*
Cellに値を設定する.
*/
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Cellの.を取得する.
if self.int_total > 0{
let cell = workItemCell(tableView, cellForRowAtIndexPath: indexPath, str_xib: "WorkItemCell")
return cell
}else{
let nocell: NoCountCell = tableView.dequeueReusableCellWithIdentifier("NoCountCell", forIndexPath: indexPath) as! NoCountCell
nocell.conditionButton.addTarget(self, action: "onClickBack:", forControlEvents: .TouchUpInside)
//初期が終わったらfalse
if self.init_loading{
nocell.conditionButton.hidden = true
nocell.messageLabel.hidden = true
}else{
nocell.conditionButton.hidden = true
nocell.messageLabel.hidden = false
}
return nocell
}
}
func workItemCell(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath,str_xib:String) ->WorkItemCell{
let wcell: WorkItemCell = tableView.dequeueReusableCellWithIdentifier(str_xib, forIndexPath: indexPath) as! WorkItemCell
wcell.separatorInset = UIEdgeInsetsZero
wcell.selectionStyle = UITableViewCellSelectionStyle.None
updateCell(wcell, atIndexPath: indexPath)
return wcell
}
func updateCell(cell:UITableViewCell,atIndexPath:NSIndexPath){
}
func showWorkItem(wcell:WorkItemCell,workdic:NSDictionary){
wcell.workdic = workdic
}
I have posted capture.
This is in Objective C.Calculate the height of cell's content in heightForRowAtIndexPath method add it in one array as
- (CGFloat)tableView:(UITableView *)t heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
text =[NSString stringWithFormat:#"%#",[content_array objectAtIndex:indexPath.row]];
CGSize textSize = [text sizeWithFont:[UIFont systemFontOfSize:14.0f] constrainedToSize:CGSizeMake(self.tblView.frame.size.width - PADDING * 3, 1000.0f)];
NSLog(#"%f",textSize.height);
[height_Array addObject:[NSString stringWithFormat:#"%f", textSize.height]];
return textSize.height;
}
Now in cellForRowAtIndexPath method set the frame of title using height array as:-
CGRect newFrame = txtTitle.frame;
newFrame.size.height = [[height_Array objectAtIndex:indexPath.row] floatValue];
txtTitle.frame = newFrame;
I finaly got answer.
But i have calculated height manually.
I calculated the label's height at each time.
This label has multi line.
Then I set height other height + the height which was calcuted.
class func heightForCatchCopy(tableView: UITableView, workdic: NSDictionary?) -> CGFloat {
struct Sizing {
static var cell: WorkItemCell?
}
if Sizing.cell == nil {
Sizing.cell = tableView.dequeueReusableCellWithIdentifier("WorkItemCell") as? WorkItemCell
}
if let cell = Sizing.cell {
cell.frame.size.width = CGRectGetWidth(tableView.bounds)
cell.workdic = workdic
let size = cell.catchcopyLabel.intrinsicContentSize()
return size.height
}
return 0
}

The text in the textview inside the table view cell is not formatted

I am trying to build a Table View in which each cell contains a UITextView with formatted text. I got everything together, and the the table view gets populated by text. The problem is that when I test it in the simulator, the text is not formatted. It gets formatted only after scrolling, when it gets refreshed.
Here I am pasting below the view controller, which calls for the tableview and for the text (from a SQLite database), and the class I use to insert the text in the UITextView and format it. I have tried to force the layout of the container, but it does not work.
The View Controller
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var myTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.myTable.estimatedRowHeight = 44.0
self.myTable.rowHeight = UITableViewAutomaticDimension
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 200
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("verseCell") as! VerseTextView
let row : Int = indexPath.row
var getVerse = databaseDB()
var verse = databaseVars()
(verse.book, verse.chapter, verse.verseText) = getVerse.getVerseBy(row, database: databasePath as String)
if verse.verseNumber == 1 {
chapterToBePassed = String(verse.chapter)
}
else {
chapterToBePassed = ""
}
cell.configure(verseChapter: chapterToBePassed, verseText: "\(verse.verseText)")
return cell
}
}
the VerseTextView class
class VerseTextView: UITableViewCell {
#IBOutlet weak var verse: UITextView!
func configure(#verseChapter: String?, verseText: String?) {
// Formats
var style = NSMutableParagraphStyle()
style.lineSpacing = 15
let font = UIFont(name: "Georgia", size: 18.0) ?? UIFont.systemFontOfSize(18.0)
let textFont = [NSFontAttributeName:font, NSParagraphStyleAttributeName : style]
let fontChapter = UIFont(name: "Georgia-Bold", size: 22.0) ?? UIFont.systemFontOfSize(22.0)
let chapterFont = [NSFontAttributeName:fontChapter]
let myText = NSMutableAttributedString()
var versettoId : String = ""
if verseChapter != ""{
let myTextChapter = "\n"+verseChapter!+" "
let capitolo = NSAttributedString(string: myTextChapter, attributes:chapterFont)
myText.appendAttributedString(capitolo)
}
let testoVerso = verseText!+" "
let verso = NSAttributedString(string: testoVerso, attributes:textFont)
myText.appendAttributedString(verso)
verse.attributedText = myText
// verse.layoutManager.ensureLayoutForTextContainer(verse.textContainer)
// verse.layoutIfNeeded()
}
}
Thanks,
S
try this ,
in cellForRowAtIndexpath
let cell = tableView.dequeueReusableCellWithIdentifier("verseCell") as? VerseTextView
if cell == nil {
VerseTextView(style: .Default, reuseIdentifier: "verseCell")
}
and implement VerseTextView(style: Style, reuseIdentifier: ReuseIdentifire)
in ur custom cell class

Getting autocomplete to work in swift

I am trying to implement autocompletion, but can't find an example that works in Swift. Below, I'm tring to convert Ray Wenderlich's autocompletion tutorial and example code from 2010. Finally, the code compiles, but the table containing possible completions does not appear, and I don't have the experience to see why it is not unhidden by shouldChangeCharactersInRange.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
#IBOutlet weak var textField: UITextField!
let autocompleteTableView = UITableView(frame: CGRectMake(0,80,320,120), style: UITableViewStyle.Plain)
var pastUrls = ["Men", "Women", "Cats", "Dogs", "Children"]
var autocompleteUrls = [String]()
override func viewDidLoad() {
super.viewDidLoad()
autocompleteTableView.delegate = self
autocompleteTableView.dataSource = self
autocompleteTableView.scrollEnabled = true
autocompleteTableView.hidden = true
}
func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool
{
autocompleteTableView.hidden = false
var substring = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
searchAutocompleteEntriesWithSubstring(substring)
return true // not sure about this - could be false
}
func searchAutocompleteEntriesWithSubstring(substring: String)
{
autocompleteUrls.removeAll(keepCapacity: false)
var indexOfPastUrls = 0
for curString in pastUrls
{
let substringRange = curString.rangeOfString(curString)
if (indexOfPastUrls == 0)
{
autocompleteUrls.append(curString)
}
indexOfPastUrls = indexOfPastUrls + 1
}
autocompleteTableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return autocompleteUrls.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let autoCompleteRowIdentifier = "AutoCompleteRowIdentifier"
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier, forIndexPath: indexPath) as UITableViewCell
let index = indexPath.row as Int
cell.textLabel.text = autocompleteUrls[index]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedCell : UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
textField.text = selectedCell.textLabel.text
}
}
Replace your searchAutocompleteEntriesWithSubstring function content with the one below. I hope it would help you.
func searchAutocompleteEntriesWithSubstring(substring: String)
{
autocompleteUrls.removeAll(keepCapacity: false)
for curString in pastUrls
{
var myString:NSString! = curString as NSString
var substringRange :NSRange! = myString.rangeOfString(substring)
if (substringRange.location == 0)
{
autocompleteUrls.append(curString)
}
}
autocompleteTableView.reloadData()
}
The table was not appearing because the UITextField delegate was not to self in viewDidLoad. There was another final issue with the table not showing the autocompletion results, but this is also fixed. Ray Wenderlich's basic Objective-C autocompletion tutorial converted to Swift:
class ViewController: UIViewController, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var textField: UITextField!
#IBOutlet var autocompleteTableView: UITableView!
// #IBOutlet weak var autocompleteTableView = UITableView(frame: CGRectMake(0,80,320,120), style: UITableViewStyle.Plain)
var pastUrls = ["Men", "Women", "Cats", "Dogs", "Children"]
var autocompleteUrls = [String]()
override func viewDidLoad() {
super.viewDidLoad()
textField.delegate = self
autocompleteTableView!.delegate = self
autocompleteTableView!.dataSource = self
autocompleteTableView!.scrollEnabled = true
autocompleteTableView!.hidden = true
}
func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool
{
println("banana")
autocompleteTableView!.hidden = false
var substring = (self.textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
searchAutocompleteEntriesWithSubstring(substring)
return true
}
func searchAutocompleteEntriesWithSubstring(substring: String)
{
autocompleteUrls.removeAll(keepCapacity: false)
println(substring)
for curString in pastUrls
{
println(curString)
var myString: NSString! = curString as NSString
var substringRange: NSRange! = myString.rangeOfString(substring)
if (substringRange.location == 0)
{
autocompleteUrls.append(curString)
}
}
autocompleteTableView!.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return autocompleteUrls.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let autoCompleteRowIdentifier = "AutoCompleteRowIdentifier"
var cell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier) as? UITableViewCell
if let tempo1 = cell
{
let index = indexPath.row as Int
cell!.textLabel.text = autocompleteUrls[index]
} else
{
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: autoCompleteRowIdentifier)
}
return cell!
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedCell : UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
textField.text = selectedCell.textLabel.text
}
}
I put together a tutorial that is full of pictures on how to recreate this now 6 year old tutorial
matthewhsingleton.com/coding-with-a-rubber-ducky/2016/5/26/… – RubberDucky4444
For future guys, that might get to work on autocomplete texfield with Swift 2, the code provided by #dane works well. but you have to change this line:
let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier, forIndexPath: indexPath) as UITableViewCell
by
let cell = UITableViewCell(style: UITableViewCellStyle.Default , reuseIdentifier: cellIdentifier)
Also, you might notice that the it is case sensitive, and doesn't work if you enter lowercase string (e.g cats) by default. So to solve this issue you can replace add the option "CaseSensitiveSearch" to the substringRange declaration (in the func searchAutocompleteEntriesWithSubstring). it should look like:
let substringRange :NSRange! = myString.rangeOfString(substring,options [.CaseInsensitiveSearch])
Hope it will help you save one day!!!
Fixed for iOS 9.0 and Swift 2:
import UIKit
class UIAutoCompleteTextField: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
#IBOutlet weak
var textField: UITextField!
let autocompleteTableView = UITableView(frame: CGRectMake(0, 80, 320, 120), style: UITableViewStyle.Plain)
var pastUrls = ["Men", "Women", "Cats", "Dogs", "Children"]
var autocompleteUrls = [String]()
override func viewDidLoad() {
super.viewDidLoad()
autocompleteTableView.delegate = self
autocompleteTableView.dataSource = self
autocompleteTableView.scrollEnabled = true
autocompleteTableView.hidden = true
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) - > Bool {
autocompleteTableView.hidden = false
let substring = (textField.text!as NSString).stringByReplacingCharactersInRange(range, withString: string)
searchAutocompleteEntriesWithSubstring(substring)
return true // not sure about this - could be false
}
func searchAutocompleteEntriesWithSubstring(substring: String) {
autocompleteUrls.removeAll(keepCapacity: false)
for curString in pastUrls {
let myString: NSString! = curString as NSString
let substringRange: NSRange! = myString.rangeOfString(substring)
if (substringRange.location == 0) {
autocompleteUrls.append(curString)
}
}
autocompleteTableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) - > Int {
return autocompleteUrls.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) - > UITableViewCell {
let autoCompleteRowIdentifier = "AutoCompleteRowIdentifier"
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier, forIndexPath: indexPath) as UITableViewCell
let index = indexPath.row as Int
cell.textLabel!.text = autocompleteUrls[index]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedCell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath) !
textField.text = selectedCell.textLabel!.text
}
}
Here's a way to add multiple tags based on "#" being typed in like twitter.
Variable typedSubstring is the global substring.
func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
autocompleteTableView!.hidden = false
var changedText = (self.textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
var items = changedText.componentsSeparatedByString("#")
if (items.count > 0) {
typedSubstring = "#" + items.lastObject as NSString
self.searchAutocompleteEntriesWithSubstring(typedSubstring)
}
return true
}
Improved on DrWhat's solution so that when you select a cell, it appends it correctly after where the user has already typed in.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
let selectedCell : UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
let selectedText = selectedCell.textLabel?.text as String!
// Remove what has been typed already
let trimmedString = selectedText.stringByReplacingOccurrencesOfString(typedSubstring, withString: "", options: NSStringCompareOptions.LiteralSearch, range: nil)
var currentTextField = textField.text
// then append to what has been typed
textField.text = currentTextField + trimmedString
Got it working with the below. The upper/lower case threw it off initially. I'm using it to autocomplete country names...
import UIKit
class billingAddressViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
#IBOutlet var countryTextField: UITextField!
#IBOutlet var countryTableView: UITableView!
var autocompleteCountries = [String]()
// Get list of countries
let countries = NSLocale.ISOCountryCodes().map { (code:String) -> String in
let id = NSLocale.localeIdentifierFromComponents([NSLocaleCountryCode: code])
return NSLocale(localeIdentifier: "en_US").displayNameForKey(NSLocaleIdentifier, value: id) ?? "Country not found for code: \(code)"
}
override func viewDidLoad() {
super.viewDidLoad()
countryTextField.delegate = self
countryTableView!.delegate = self
countryTableView!.dataSource = self
countryTableView!.scrollEnabled = true
countryTableView!.hidden = true
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
print("text field has changed")
countryTableView!.hidden = false
let substring = (self.countryTextField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
print(substring)
searchAutocompleteEntriesWithSubstring(substring)
return true
}
func searchAutocompleteEntriesWithSubstring(substring: String) {
autocompleteCountries.removeAll(keepCapacity: false)
print(substring)
for curString in countries {
//print(curString)
let myString: NSString! = curString.lowercaseString as NSString
let substringRange: NSRange! = myString.rangeOfString(substring.lowercaseString)
if (substringRange.location == 0) {
autocompleteCountries.append(curString)
}
}
countryTableView!.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return autocompleteCountries.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let autoCompleteRowIdentifier = "AutoCompleteRowIdentifier"
var cell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier) as UITableViewCell!
if let tempo1 = cell {
let index = indexPath.row as Int
cell!.textLabel!.text = autocompleteCountries[index]
}
else {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: autoCompleteRowIdentifier)
}
return cell!
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedCell : UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
countryTextField.text = selectedCell.textLabel!.text
countryTableView.hidden = true
}
}
table view added without storyboard
class ViewController: UIViewController , UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
#IBOutlet weak var textField: UITextField!
var autocompleteTableView: UITableView!
var pastUrls = ["Men", "Women", "Cats", "Dogs", "Children","aaaaaaaaa","aaaaaaaaaaaaaaaaaaa","aaaaaaaaa","a","aa","aaa"]
var autocompleteUrls = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
autocompleteTableView = UITableView(frame: CGRectMake(self.textField.bounds.minX,self.textField.bounds.maxY,self.textField.bounds.width,self.textField.bounds.height * 4), style: UITableViewStyle.Plain)
textField.delegate = self
autocompleteTableView.delegate = self
autocompleteTableView.dataSource = self
autocompleteTableView.scrollEnabled = true
autocompleteTableView.hidden = false
autocompleteTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.view.addSubview(autocompleteTableView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool
{
autocompleteTableView.hidden = false
var substring = (self.textField.text! as NSString).stringByReplacingCharactersInRange(range, withString: string)
searchAutocompleteEntriesWithSubstring(substring)
return true // not sure about this - could be false
}
func searchAutocompleteEntriesWithSubstring(substring: String)
{
autocompleteUrls.removeAll(keepCapacity: false)
for curString in pastUrls
{
var myString:NSString! = curString as NSString
var substringRange :NSRange! = myString.rangeOfString(substring)
if (substringRange.location == 0)
{
autocompleteUrls.append(curString)
}
}
autocompleteTableView.reloadData()
//autocompleteTableView.hidden = false
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return autocompleteUrls.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let autoCompleteRowIdentifier = "cell"
var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier(autoCompleteRowIdentifier, forIndexPath: indexPath) as UITableViewCell
let index = indexPath.row as Int
cell.textLabel!.text = autocompleteUrls[index]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedCell : UITableViewCell = tableView.cellForRowAtIndexPath(indexPath)!
textField.text = self.autocompleteUrls[indexPath.row]
self.autocompleteTableView.hidden = true
}
}
This post helped me thanks, just in case you guys are working with google places API in swift 3 and you need case-insensitive here is the updated code you just have to put:
let subStringRange : NSRange! = myString.range(of: substring, options: .caseInsensitive)
Replace cellForRowAtIndexPath with following function
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell()
var data = autocompleteUrls[indexPath.row]
cell.textLabel?.text = data as String
return cell
}
Here you have a nice-to-have library in order to simplify that work: https://github.com/apasccon/SearchTextField
Add view.addSubview(autocompleteTableView)
in your viewdidload. It will work.

get the clicked imageview swift

I want to know which imageview was clicked by the user I am using the following code, but it is not calling the leftTapView and rightTapView functions
class CustomTableViewCell : UITableViewCell {
#IBOutlet var leftTeamImage: UIImageView!
#IBOutlet var rightTeamImage: UIImageView!
#IBOutlet var rightTeamNameLabel: UILabel!
#IBOutlet var leftTeamNameLabel: UILabel!
#IBOutlet var leftTeamScoreLabel: UILabel!
#IBOutlet var rightTeamScoreLabel: UILabel!
#IBOutlet var leftView : UIView!
#IBOutlet var rightView : UIView!
let lettTapRec = UITapGestureRecognizer()
let rightTapRec = UITapGestureRecognizer()
ScoreLabel.text = leftTeamScore
rightTeamNameLabel.text = rightTeamName.uppercaseString
rightTeamScoreLabel.text = rightTeamScore
}
func load(#leftTeamName: String, rightTeamName: String, leftTeamScore: Int, rightTeamScore: Int) {
leftTeamNameLabel.text = leftTeamName.uppercaseString
leftTeamScoreLabel.text = String(leftTeamScore)
rightTeamNameLabel.text = rightTeamName.uppercaseString
rightTeamScoreLabel.text = String(rightTeamScore)
lettTapRec.addTarget(self, action: "leftTapView")
leftView.userInteractionEnabled = true
leftView.addGestureRecognizer(lettTapRec)
//
rightTapRec.addTarget(self, action: "rightTapView")
rightView.userInteractionEnabled = true
rightView.addGestureRecognizer(rightTapRec)
}
func leftTapView(sender: AnyObject){
println("left")
}
func rightTapView(sender: AnyObject){
println("left")
}
}
protocol ImageTappedProtocols {
func leftImageTapped(imageView : UIImage)
func rightImageTapped(imageView: UIImage)
}
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView : UITableView!
var items: [(String, String)] = [
("My", "swift 1.jpeg"),
("Name", "swift 2.jpeg"),
("is", "swift 3.jpeg"),
("Atif", "swift 4.jpeg"),
("Farrukh", "swift 5.jpeg")
]
var team1 :[String] = []
var team2 :[String] = []
var id : [String] = []
var team1_bets : [Int] = []
var team2_bets : [Int] = []
var end_date : [String] = []
var list = Dictionary<String, String>()
var count : Int = 0
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:CustomTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("customCell") as CustomTableViewCell
// this is how you extract values from a tuple
var (title, image) = items[indexPath.row]
var teama: String = team1[indexPath.row]
var teamb: String = team2[indexPath.row]
var teamAScore : Int = team1_bets[indexPath.row]
var teamBScore : Int = team2_bets[indexPath.row]
cell.backgroundColor = UIColor(red: 123, green: 225, blue: 38, alpha: 0.2)
return cell
}
func tableView(tableView : UITableView, didSelectedRowAtIndexPath indexPath : NSIndexPath){
//tableView.deselectRowAtIndexPath(indexPath, animated: true)
println("You selected cell #\(indexPath.row)!")
let indexPath = tableView.indexPathForSelectedRow();
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as UITableViewCell!;
println(currentCell.textLabel.text)
}
func tableView(tableView : UITableView, didSelectRowAtIndexPath indexPath : NSIndexPath){
//tableView.deselectRowAtIndexPath(indexPath, animated: true)
println("You selected cell #\(indexPath.row)!")
let indexPath = tableView.indexPathForSelectedRow();
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as UITableViewCell!
println(currentCell.contentView)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let urlAsString = "http://codespikestudios.com/betting_app/bet/get_events/1"
//let urlAsString = "http://api.topcoder.com/v2/challenges?pageSize=2"
let url: NSURL = NSURL(string: urlAsString)!
let urlSession = NSURLSession.sharedSession()
//2
let jsonQuery = urlSession.dataTaskWithURL(url, completionHandler: { data, response, error -> Void in
if (error != nil) {
println(error.localizedDescription)
}
var err: NSError?
// 3
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSArray
if (err != nil) {
println("JSON Error \(err!.localizedDescription)")
}
// 4
println(jsonResult)
println(jsonResult.count)
println(jsonResult[1].valueForKey("cat_name") as String)
var dictionary = Dictionary<String, String>()
self.count = jsonResult.count
for var i = 0; i < self.count; i++ {
self.team1 = jsonResult.valueForKey("team1") as Array
self.team2 = jsonResult.valueForKey("team2") as Array
self.team1_bets = jsonResult.valueForKey("team1_bets") as Array
self.team2_bets = jsonResult.valueForKey("team2_bets") as Array
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
//let jsonDate: String! = jsonResult["date"] as NSString
//let jsonTime: String! = jsonResult["time"] as NSString
//println(jsonTime)
})
// 5
jsonQuery.resume()
var nib = UINib(nibName: "MyTableViewCell", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: "customCell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
this is all I get
You selected cell #3!
<UITableViewCellContentView: 0x7f871b687350; frame = (0 0; 580 136.5); opaque = NO; gestureRecognizers = <NSArray: 0x7f871b68c180>; layer = <CALayer: 0x7f871b687420>>
You will want to add a target when you initialize your gesture recognizers. That would look like, for instance:
let leftTapRect = UIGestureRecognizer(target: self, action: "leftTapView:")
In addition, you will need to add a sender argument to your event handlers leftTapView and rightTapView:
func leftTapView(sender: AnyObject) {
...
}
solved my problem, Actually i had set my view's alpha to 0, when I set it to 1 and made the set the background as Clear Colour it started working. Rest the working perfectly. If someone can explain the reason of why setting alpha doesnt trigger the tap gesture I will gladly accept hi/her answer as accepted.
A view with an alpha of 0.0 won't receive touch events.
From the Event Handling guide:
"Note that a view also does not receive touch events if it’s hidden or transparent."
From the Creating Views documentation:
"A hidden view does not receive touch events from the system."

Resources