how to hide the section title when clicked search bar using ios 8 UISearchController? - ios8

This is the previous screen.
Then, I clicked the search bar:
Code is below:
// MARK: - searchController
func initSearchController() {
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
controller.searchBar.backgroundColor = UIColor.clearColor()
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
}
Please help me. Thanks.

Set the title of the section to nil, if there are no rows in that section, this would hide the section title
// Set the title of the section header, return nil if no rows in that section
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if self.tableView(tableView, numberOfRowsInSection: section) == 0 {
return nil
} else {
return "section title \(section)"
}
}
This will work, assuming tableView(tableView: UITableView, numberOfRowsInSection section: Int) is implemented properly to reflect the number of sections based on the search result.
If you want to remove the section title altogether when the search bar is active, then just add this
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if self.resultSearchController.active {
return nil
} else {
return "section title \(section)"
}
}

Related

Need multiple tableview cells with different rows

I have one table view using a different cell based on what tab you select. It is working, although the 1st one seems to be controlling the height. I have one row in the first tab but 2 in the second and both just show 1.
I'm wondering if I need to clear dequeueReusableCell on tab select or something like that. Any Ideas?
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if activeTab == "tab1" {
return someService.tab1.count
} else {
return someService.tab2.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if activeTab == "tab1" {
if let cell = tableView.dequeueReusableCell(withIdentifier: "Tab1Cell") as? Tab1Cell {
let tab1 = someService.tab1[indexPath.row]
cell.updateView(tab1: tab1)
return cell
} else {
return Tab1Cell()
}
} else {
if let cell = tableView.dequeueReusableCell(withIdentifier: "Tab2Cell") as? Tab2Cell {
let tab2 = someService.tab2[indexPath.row]
cell.updateView(tab2: tab2)
return cell
} else {
return Tab2Cell()
}
}
}
I'm also fixing the scroll with this:
func fixTableViewSize() {
let cells = self.notesTable.visibleCells
var heightOfTableView = 0
for cell in cells {
print("cell")
heightOfTableView += Int(cell.frame.height)
}
self.tableViewHeightConstraint.constant = CGFloat(heightOfTableView)
self.buttonFromTableTopConstraint.constant = CGFloat(heightOfTableView)
}

is it possible to hide message bubble

I'm using JSQMessagesViewController to implement chat in my iOS app. I need to display some system messages in the middle of the screen (see attached picture). I was hoping that I can achieve that by using the message bottom label and not showing the message bubble. But I haven't found a way to hide the message bubble. Is it possible? Thanks.
I sort of achieved what I need by overriding collectionView sizeForItemAtIndexPath function and return a height of kJSQMessagesCollectionViewCellLabelHeightDefault, then return nil for both messageBubbleImageDataForItemAtIndexPath and avatarImageDataForItemAtIndexPath
override func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let userMessageCellSize = super.collectionView(collectionView, layout: collectionViewLayout, sizeForItemAtIndexPath: indexPath)
let message = messages[indexPath.item]
if message.type == MessageType.System {
// for system message, only show bottom label, plus the top label when timestamp needs to be displayed
// this will hide the avatar image and message bubble which are not needed for system messages.
var newHeight: CGFloat = 0
if (shouldDisplayTimestamp(indexPath)) {
newHeight = kJSQMessagesCollectionViewCellLabelHeightDefault * 2
} else {
newHeight = kJSQMessagesCollectionViewCellLabelHeightDefault
}
return CGSizeMake(userMessageCellSize.width, newHeight)
} else {
return super.collectionView(collectionView, layout: collectionViewLayout, sizeForItemAtIndexPath: indexPath)
}
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let message = messages[indexPath.item]
if message.type == MessageType.System {
return nil
}
if message.senderId == senderId{
return self.outgoingBubbleImageView
} else {
return self.incomingBubbleImageView
}
}
override func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
let message = messages[indexPath.item]
if message.type == MessageType.System {
return nil
}
if let avatar = avatars[message.senderDisplayName] {
return avatar
} else {
setupAvatarImage(message.senderDisplayName, imageUrl: message.profileImgUrl, incoming: true)
return avatars[message.senderDisplayName]
}
}

Segmented Tab IBAction won't pass to cellForRowAtIndexPath

My problem is that my segmented control won't pass information to my cellForRowAtIndexPath method in my tableView. When each tab is selected, I wanted to my table view to display different data.
Here is a snippet of my code from where I think my problem originates:
var parsedDataForTableView : ParseForDetailView? {
didSet {
self.selectedIndex = (parsedDataForTableView?.tabSelected)!
self.tableView.rowHeight = (parsedDataForTableView?.tableViewRowHeight)!
self.tableView.reloadData()
}
}
var selectedIndex = Int()
override func viewDidLoad() {
super.viewDidLoad()
self.parsedDataForTableView = ParseForDetailView(segmentedTabSelected: 0, primaryBarData: self.primaryBarDetails!, secondaryBarData: self.secondaryBarDetails!)
configureView()
configureNavigationBarItems()
setImageShadow()
}
#IBAction func switchBetweenTabs(sender: AnyObject) {
if segmentControl.selectedSegmentIndex == 0 {
print("Drinks Selected")
self.selectedIndex = 0
print(self.selectedIndex)
self.parsedDataForTableView = ParseForDetailView(segmentedTabSelected: 0, primaryBarData: self.primaryBarDetails!, secondaryBarData: self.secondaryBarDetails!)
self.tableView.reloadData()
}
if segmentControl.selectedSegmentIndex == 1 {
print("Entertainment Selected")
self.selectedIndex = 1
print(self.selectedIndex)
self.parsedDataForTableView = ParseForDetailView(segmentedTabSelected: 1, primaryBarData: self.primaryBarDetails!, secondaryBarData: self.secondaryBarDetails!)
self.tableView.reloadData()
}
if segmentControl.selectedSegmentIndex == 2 {
print("Info Selected")
self.selectedIndex = 2
print(self.selectedIndex)
self.parsedDataForTableView = ParseForDetailView(segmentedTabSelected: 2, primaryBarData: self.primaryBarDetails!, secondaryBarData: self.secondaryBarDetails!)
self.tableView.reloadData()
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("detailViewCell") as! DetailViewCell
print(self.selectedIndex)
if self.selectedIndex == 0 {
cell.drinkLabel.text = self.parsedDataForTableView?.drinksArray[indexPath.section][indexPath.row]
cell.priceLabel.text = self.parsedDataForTableView?.priceArray[indexPath.section][indexPath.row]
cell.entertainmentLabel.text = ""
} else if self.selectedIndex == 1 {
cell.entertainmentLabel.text = self.parsedDataForTableView?.entertainmentString
cell.drinkLabel.text = ""
cell.priceLabel.text = ""
} else if self.selectedIndex == 2 {
// finish this...
cell.drinkLabel.text = "Info"
cell.priceLabel.text = "Info"
cell.entertainmentLabel.text = "Info"
}
return cell
}
So above we have my IBAction connected to my segmented tab and my cellForRowAtIndexPath method. I want to pass the selectedIndex property into the cellForRowAtIndexPath method to switch between the different data I want to display - initialized in my didSet up top.
When I run the code the view loads just fine with the first segment's information (0th segment index) displaying correctly and my print(self.selectedIndex) within my cellForRowAtIndexPath prints "0" for every cell printed as planned. When I tap the second and third segmented index that same print function prints nothing.
When I print the information inside my IBAction to the console everything is updating correctly.
Why does only my first index register with the cellForRowAtIndexPath method?
I may have mislead you to believe my problem lied somewhere in my logic. My problem was that in my numberOfRowsInSection I didn't account for all the three segmented tab cases therefore my data could not be displayed properly in the table view.
Thank you #NoName

Error :"Cannot subscript a value of type'[String: Array<String>]' with an index of type 'Int'"

Assignment: "Create an application that displays a list of gas stations and their gas prices and distance. Store the information into a Dictionary. Display the results in a table view. Let the user select an entry and then display a UIAlert dialog showing the entry."
I am working on the dictionary part. The code for the dictionary is
"var gasStation = ["76": ["$2.76", "1.2 miles"],
"Arco":["$2.56", "2.4 miles"],
"Shell":["$3.54", "3.5 miles"],
"Tower mart": ["$2.36", "5.7 miles"]]"
The error pops up on this line of code
cell!.textLabel!.text = gasStation[indexPath.row]
Here is the New Updated code
import UIKit
class ViewController: UIViewController,UITableViewDataSource, UITableViewDelegate {
let dwarves = [ "Sleepy", "Sneezy", "bashful", "Happy"]
let gasStation = ["76": ["$2.76", "1.2 miles"],
"Arco":["$2.56", "2.4 miles"],
"Shell":["$3.54", "3.5 miles"],
"Tower-Mart": ["$2.36", "5.7 miles"]]
var gasStationNames = Array(gasStation) // error: "ViewController.Type' does not have a member named 'gasStation'
let simpleTableIdentifier = "SimpleTableIdentifier"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return dwarves.count
}
func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) ->UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier(
simpleTableIdentifier) as? UITableViewCell
if (cell == nil) {
cell = UITableViewCell(
style: UITableViewCellStyle.Default, reuseIdentifier: simpleTableIdentifier)
}
cell!.textLabel?.text = dwarves[indexPath.row]
return cell!
}
}
This is how you get an array of all the gas Station names.
let gasStationNames = Array(gasStation.keys)
But it will not be in the same order.
And for assigning it to the tableView:
cell!.textLabel!.text = gasStationNames[indexPath.row]
Here, you can index gasStationNames with indexPath.row of type Int as it is of type Array. And to get a value out of Dictionary, you should pass a key of proper type.
You should have a look at this document page
EDIT
Assign gasStationNames in your cellForRow
let gasStationNames = Array(gasStation.keys)
and then assign to cell's textLabel
cell!.textLabel!.text = gasStationNames[indexPath.row]

How to implant a sectioned tableview with Parse in Swift

I am struggling to figure out how to implement a sectioned table view using parse. I am able to correctly section the table view if I don't load the names I want. However, when I use parse the names don't load in time and therefore are missed as it is async.
When I reload the table in queryFriends() it doesn't show up. My theory is that the table isn't sectioned again.
How do I make the table section again?
Or does anyone have any ideas?
Thanks for your help
import UIKit
import Parse
import Foundation
class MyFriendsTableView: UITableViewController, UITableViewDataSource, UITableViewDelegate{
var names:[String] = []
/*var names: [String] = [
"AAAA",
"Clementine",
"Bessie",
"Yolande",
"Tynisha",
"Ellyn",
"Trudy",
"Fredrick",
"Letisha",
"Ariel",
"Bong",
"Jacinto",
"Dorinda",
"Aiko",
"Loma",
"Augustina",
"Margarita",
"Jesenia",
"Kellee",
"Annis",
"Charlena",
"!##",
"###"
]*/
override func viewDidLoad() {
super.viewDidLoad()
self.refreshControl = UIRefreshControl()
self.refreshControl?.attributedTitle = NSAttributedString(string: "Pull to refresh")
self.refreshControl?.addTarget(self, action: "queryFriends", forControlEvents: UIControlEvents.ValueChanged)
self.tableView.addSubview(refreshControl!)
}
override func viewDidAppear(animated: Bool) {
UIApplication.sharedApplication().statusBarHidden = false
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent
queryFriends()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func queryFriends() {
let currentUser = PFUser.currentUser()?.username
let predicate = NSPredicate(format: "status = 'Friends' AND fromUser = %# OR status = 'Friends' AND toUser = %#", currentUser!, currentUser!)
var query = PFQuery(className: "FriendRequest", predicate: predicate)
var friends:[String] = []
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
if let objects = objects as? [PFObject] {
for object in objects {
if object["toUser"] as? String != currentUser {
friends.append(object["toUser"] as! String)
} else if object["fromUser"] as? String != currentUser {
friends.append(object["fromUser"] as! String)
}
}
}
} else {
// Log details of the failure
println("Error: \(error!) \(error!.userInfo!)")
}
self.names = friends
self.tableView.reloadData()
self.refreshControl?.endRefreshing()
}
}
/* type to represent table items
`section` stores a `UITableView` section */
class User: NSObject {
let name: String
var section: Int?
init(name: String) {
self.name = name
}
}
// custom type to represent table sections
class Section {
var users: [User] = []
func addUser(user: User) {
self.users.append(user)
}
}
// `UIKit` convenience class for sectioning a table
let collation = UILocalizedIndexedCollation.currentCollation()
as! UILocalizedIndexedCollation
// table sections
var sections: [Section] {
// return if already initialized
if self._sections != nil {
return self._sections!
}
// create users from the name list
var users: [User] = names.map { name in
var user = User(name: name)
user.section = self.collation.sectionForObject(user, collationStringSelector: "name")
return user
}
// create empty sections
var sections = [Section]()
for i in 0..<self.collation.sectionIndexTitles.count {
sections.append(Section())
}
// put each user in a section
for user in users {
sections[user.section!].addUser(user)
}
// sort each section
for section in sections {
section.users = self.collation.sortedArrayFromArray(section.users, collationStringSelector: "name") as! [User]
}
self._sections = sections
return self._sections!
}
var _sections: [Section]?
// table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.sections.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.sections[section].users.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let user = self.sections[indexPath.section].users[indexPath.row]
let cell = tableView.dequeueReusableCellWithIdentifier("UITableViewCell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel!.text = user.name
return cell
}
/* section headers
appear above each `UITableView` section */
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
// do not display empty `Section`s
if !self.sections[section].users.isEmpty {
return self.collation.sectionTitles[section] as? String
}
return ""
}
/* section index titles
displayed to the right of the `UITableView` */
override func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject] {
return self.collation.sectionIndexTitles
}
override func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
return self.collation.sectionForSectionIndexTitleAtIndex(index)
}
}
You can try to clear the _sections in queryFriends:
self._sections = nil
self.names = friends
self.tableView.reloadData()
self.refreshControl?.endRefreshing()

Resources