Remove specific subviews (swift) - swift

Question: How Can i just remove all the subview of UIButton? if i remove all subviews, it will remove the cell title as well.
This is my code:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("idcell", forIndexPath: indexPath) as UITableViewCell
let lblTitle : UILabel = cell.contentView.viewWithTag(101) as! UILabel
lblTitle.text = (deptId[indexPath.row] as? String)! + " " + (deptDesc[indexPath.row] as? String)!
var height:CGFloat = 0
cell.backgroundColor = UIColor.whiteColor()
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
if(indexPath == selectedIndexPath){
cell.backgroundColor = UIColor.grayColor()
for i in 0...deptProfile.count-1 {
let deptmentProfile = UIButton(frame: CGRectMake(0,44+height,400,41))
deptmentProfile.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
height = height+41
deptmentProfile.setTitle(deptProfile[i] as! String, forState: UIControlState.Normal)
deptmentProfile.setTitleColor(UIColor.blackColor(), forState: .Normal)
deptmentProfile.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left
deptmentProfile.backgroundColor = UIColor.whiteColor()
deptmentProfile.titleEdgeInsets = UIEdgeInsetsMake(0, 40, 0, 0); //margin to the left
cell.addSubview(deptmentProfile)
}
cell.accessoryType = UITableViewCellAccessoryType.None
}
return cell
}

try like this :
for view in subviews {
if view is UIButton {
view.removeFromSuperview()
}
}
NicolasMiari's suggest way:
for view in subviews where view is UIButton{
view.removeFromSuperview()
}

If your just wanna remove all subviews from deptmentProfile
for subview in deptmentProfile.subviews {
subview.removeFromSuperview()
}
if you mean remove the subview which is type of UIButton, using where clause is a proper and elegant way
for subview in testButton.subviews where subview is UIButton {
subview.removeFromSuperview()
}

Related

UITableViewCell Selected Background Color on DidSelectRow

I want to change the background when I select the table. Right now, when I select two tables, the background changes to 2. I just want to change the background of the last table I chose. So just change the background of one table, not two. Change the background of the last painting I chose.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == self.tableView1 {
let cell:DeviceTableViewCell2 = tableView1.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! DeviceTableViewCell2
cell.selectionStyle = .none
cell.backgroundColor = GradientColor(UIGradientStyle.diagonal, frame: self.view.frame, colors: [UIColor.flatPowderBlueDark, UIColor.flatSand])
}
if tableView == self.tableView2 {
let cell:DeviceTableViewCell2 = tableView2.dequeueReusableCell(withIdentifier: cellIdNew, for: indexPath) as! DeviceTableViewCell2
cell.selectionStyle = .none
cell.backgroundColor = GradientColor(UIGradientStyle.diagonal, frame: self.view.frame, colors: [UIColor.flatPowderBlueDark, UIColor.flatSand])
}
if tableView == self.tableView3 {
let cell:DeviceTableViewCell2 = tableView3.dequeueReusableCell(withIdentifier: cellIdNew2, for: indexPath) as! DeviceTableViewCell2
cell.selectionStyle = .none
cell.backgroundColor = GradientColor(UIGradientStyle.diagonal, frame: self.view.frame, colors: [UIColor.flatPowderBlueDark, UIColor.flatSand])
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView == self.tableView1 {
let selectedCell:UITableViewCell = tableView1.cellForRow(at: indexPath)!
selectedCell.contentView.backgroundColor = UIColor.flatGray
}
if tableView == self.tableView2 {
let selectedCell2:UITableViewCell = tableView2.cellForRow(at: indexPath)!
selectedCell2.contentView.backgroundColor = UIColor.flatGray
}
if tableView == self.tableView3 {
let selectedCell3:UITableViewCell = tableView3.cellForRow(at: indexPath)!
selectedCell3.contentView.backgroundColor = UIColor.flatGray
}
Do not change the backgroundColor of the contentView or of the cell itself, use the selectedBackgroundView instead:
cell.backgroundView = UIView()
cell.backgroundView?.backgroundColor = // your color when not selected
cell.selectedBackgroundView = UIView()
cell.selectedBackgroundView?.backgroundColor = // your color when selected
After this initial setup, there is no need to change anything. Everything will work automatically.
Do not set cell.selectionStyle = .none because that will disable selection completely.

How can I change UITableViewCell background color with a switch?

I'm making a dark mode switch, and I'm only missing the cells to change their color to black when I turn it on, how can this be done? Thanks.
You can do it like below.
tableView.cellForRow(at: indexPath)?.backgroundColor = UIColor.red
Simply add this method to your class and attach UISwitch value change to this action:
#IBAction func changeColorAction(_ sender: UISwitch) {
let visibleCells: [UITableViewCell] = tableView.visibleCells
for cell in visibleCells {
if sender.isOn {
cell.contentView.backgroundColor = UIColor.darkGray
}else {
cell.contentView.backgroundColor = UIColor.white
}
}
}
then, implement this in your tableView delegate method:
internal func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "identifier", for: indexPath)
if switch.isOn {
cell.contentView.backgroundColor = UIColor.darkGray
}else {
cell.contentView.backgroundColor = UIColor.white
}
return cell
}

Custom UIImageView in UITableViewCell being cut off in subsequent cells - Swift

UITableViewCell Custom UIImageView
Image:
Custom TableViewCell UIImageView
If you click on the link above, you'll see that after the first row, the custom UIImageView is being cut off horizontally and then vertically in subsequent rows. Any ideas on how to fix this?
In viewDidLoad I changes row heights as follows:
// Set cell row height
self.tableView.rowHeight = 60
Here's the code for the TableView:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var count = Int()
if self.names.count != 0 {
count = self.names.count
} else if self.names.count == 0 {
count = 1
}
return count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
for view in cell.contentView.subviews {
// Clear subviews
view.removeFromSuperview()
}
// Customize separator width
tableView.separatorInset = UIEdgeInsetsZero
cell.separatorInset = UIEdgeInsetsZero
cell.layoutMargins = UIEdgeInsetsZero
cell.preservesSuperviewLayoutMargins = false
// Create imageView
let imageView = UIImageView(frame: CGRectMake(10, 5, 50, 50))
imageView.contentMode = UIViewContentMode.ScaleAspectFit
imageView.layer.cornerRadius = 25
imageView.clipsToBounds = true
cell.contentView.addSubview(imageView)
// Create textLabel
let textLabel = UILabel(frame: CGRectMake(70, 10, self.view.frame.width, 20))
textLabel.font = UIFont(name: "Arial", size: 15.0)
textLabel.textAlignment = .Left
cell.contentView.addSubview(textLabel)
// Create lastMessageLabel
let lastMessageLabel = UILabel(frame: CGRectMake(70, 30, self.view.frame.width, 20))
lastMessageLabel.font = UIFont(name: "Arial", size: 12)
lastMessageLabel.textAlignment = .Left
lastMessageLabel.textColor = UIColor.grayColor()
cell.contentView.addSubview(lastMessageLabel)
if self.names.count != 0 {
// Add contact cell
imageView.image = self.images[indexPath.row]
textLabel.text = self.names[indexPath.row] as? String
lastMessageLabel.text = self.lastMessage[indexPath.row] as? String
}
if self.names.count == 0 {
// Add warning
imageView.image = UIImage(named: "user-placeholder.png")
textLabel.text = "No users saved :("
lastMessageLabel.text = "Tap the search tab to find users."
}
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if self.names.count != 0 {
print(self.names.count)
print(self.names[indexPath.row])
print(self.ids[indexPath.row])
self.selectedUserName = self.names[indexPath.row] as! String
self.selectedUserId = self.ids[indexPath.row] as! String
self.selectedUserImage = self.images[indexPath.row]
self.performSegueWithIdentifier("chat", sender: self)
}
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete && self.userRef.savedUsers.count != 0 {
startActivityIndicator()
let savedUsers = NSMutableArray()
for user in self.userRef.savedUsers {
if user as! String != self.userRef.savedUsers[indexPath.row] as! String {
savedUsers.addObject(user as! String)
}
}
self.rootRef.child("users").child((FIRAuth.auth()?.currentUser?.uid)!).child("savedUsers").setValue(savedUsers, withCompletionBlock: { (error: NSError?, FIRDatabaseReference: FIRDatabaseReference) -> Void in
if error == nil {
print("deleted: \(self.userRef.savedUsers[indexPath.row])")
// Remove user
self.userRef.savedUsers.removeObject(self.userRef.savedUsers[indexPath.row])
self.names.removeObjectAtIndex(indexPath.row)
self.images.removeAtIndex(indexPath.row)
self.lastMessage.removeObjectAtIndex(indexPath.row)
self.stopActivityIndicator()
self.loadUsers()
self.displayAlert("Contact Deleted", message: "The user has been removed from your contacts.")
} else {
self.stopActivityIndicator()
self.displayAlert("Delete Failed", message: "Please try again later.")
}
})
}
}
EDIT:
The problem was imageView.contentMode = UIViewContentMode.ScaleAspectFit which needed to be .ScaleAspectFill

Expandable cell with dynamic data (swift)

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("idcell", forIndexPath: indexPath) as UITableViewCell
let lblTitle : UILabel = cell.contentView.viewWithTag(101) as! UILabel
lblTitle.text = (deptId[indexPath.row] as? String)! + " " + (deptDesc[indexPath.row] as? String)!
var height:CGFloat = 0
cell.backgroundColor = UIColor.whiteColor()
cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator
if(indexPath == selectedIndexPath){
cell.backgroundColor = UIColor.grayColor()
for i in 0...deptProfile.count-1{
let deptmentProfile = UIButton(frame: CGRectMake(0,44+height,400,41))
deptmentProfile.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
height = height+41
deptmentProfile.setTitle(deptProfile[i] as! String, forState: UIControlState.Normal)
deptmentProfile.setTitleColor(UIColor.blackColor(), forState: .Normal)
deptmentProfile.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left
deptmentProfile.backgroundColor = UIColor.whiteColor()
deptmentProfile.titleEdgeInsets = UIEdgeInsetsMake(0, 40, 0, 0); //margin to the left
cell.addSubview(deptmentProfile)
}
cell.accessoryType = UITableViewCellAccessoryType.None
}
return cell
}
Question: since my expanded data is dynamic,(In coding)deptProfrile is dynamic. How can i clear the cell content? it seems the subview will remain to the cell every time.
You should notice that the cell is reused, so, you have not coded for the else case for that if: if(indexPath == selectedIndexPath). You should provide the code for UI for that else.
You can give the estimated cell height for the tableview, so it will expand the cell for you.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
if(indexPath == selectedIndexPath){
var cellHeight = 100 // Assume this is the height when deptProfile.count = 0
cellHeight = cellHeight + 44 * deptProfile.count
return cellHeight
}
return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}

Remove the subView inside Cell

In my ViewController, I have a variable:
var shareButtonTapped = false
I want when I click the shareButton on the navigationBar, it will show the shareButton all of the cell, except the cell which indexPath.row == 0.
Here is the action of shareButton:
#IBAction func shareButtonTapped(sender: AnyObject) {
shareButtonTapped = !shareButtonTapped
collectionView.reloadData()
}
And here is the CollectionViewDataSource method:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! GiftCollectionViewCell
if shareButtonTapped {
cell.gift = gifts[indexPath.row]
let shareButton = FBSDKShareButton(frame: CGRect(x: 0, y: 0, width: 80, height: 30))
shareButton.tag = 1
let photo = FBSDKSharePhoto()
photo.image = gifts[indexPath.row].image
photo.userGenerated = true
let content = FBSDKSharePhotoContent()
content.photos = [photo]
content.contentURL = NSURL(string: "http://www.fantageek.com")
shareButton.shareContent = content
cell.contentView.addSubview(shareButton)
return cell
} else {
cell.gift = gifts[indexPath.row]
return cell
}
}
It worked:
But I want to click this shareButton on NavigationBar again, all of shareButton inside each cell will disappear. How to do this?
Any helps would be appreciated. Thanks.
Use removeFromSuperview() method inside your else block:
else {
cell.gift = gifts[indexPath.row]
for subview in cell.contentView.subviews {
if subview is FBSDKShareButton {
subview.removeFromSuperview()
}
}
return cell
}
Better approach will be to keep the share button always be part of cell. And show and hide the button based on status of shareButtonTapped of bar button.
Let's say your button name is shareImage then in cellForRow
cell.shareButton.hidden = false
if(shareButtonTapped){
cell.shareButton.hidden = true
}