I've set constraints and everything but there's a translucent white "screen" covering the lower part of my screen. It's not fixed to my tableview because when I scroll down the button gets pulled up and is visible but the screen stays there. At first I thought it was a rogue view but it's not so I'm not sure what's going on. Any pointers on what I should be looking at to solve this problem? Here's a picture:
Here is my code (a little untidy because this is my first project in swift):
import UIKit
class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var buttonView: UIView!
#IBOutlet weak var button: UIButton!
#IBOutlet weak var tableView: UITableView!
let manager = WorkoutDataSource()
let gradientLayer = CAGradientLayer()
var workouts = []
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
self.workouts = manager.getWorkOuts()
let borderAlpha : CGFloat = 0.7
let cornerRadius : CGFloat = 5.0
button.backgroundColor = UIColor.clearColor()
button.layer.borderWidth = 1.0
button.layer.borderColor = UIColor(white: 1.0, alpha: borderAlpha).CGColor
button.layer.cornerRadius = cornerRadius
let heightOfVisibleTableViewArea = tableView.bounds.height - topLayoutGuide.length - bottomLayoutGuide.length
let numberOfRows = tableView.numberOfRowsInSection(0)
tableView.rowHeight = heightOfVisibleTableViewArea / CGFloat(numberOfRows)
let color1 = UIColor(hue: 0.9528, saturation: 0.4, brightness: 1, alpha: 1.0) /* #ff759d */
let color2 = UIColor(hue: 0.0167, saturation: 0.25, brightness: 0.95, alpha: 1.0) /* #ffb1b1 */
let color3 = UIColor(hue: 0.2528, saturation: 0.11, brightness: 0.85, alpha: 1.0) /* #f3bbb4 */
let color4 = UIColor(hue: 0.3833, saturation: 0.21, brightness: 0.91, alpha: 1.0) /* #cedbc2 */
let color5 = UIColor(hue: 0.4417, saturation: 0.62, brightness: 0.97, alpha: 1.0) /* #b7eac7 */
let color6 = UIColor(hue: 0.4528, saturation: 0.91, brightness: 0.81, alpha: 1.0) /* #12d19e */ /* #5ef9c3 */
//let color7 = UIColor(hue: 0.5833, saturation: 0.7, brightness: 0.68, alpha: 1.0) /* #346fae */
let color7 = UIColor.flatNavyBlueColorDark()
gradientLayer.colors = [color1, color2, color3, color4, color5, color6, color7]
view.backgroundColor = UIColor.flatNavyBlueColorDark()
setTableViewBackgroundGradient(color7, bottomColor: color1)
self.navigationController?.navigationBar.backgroundColor = UIColor.flatNavyBlueColorDark()!
// Do any additional setup after loading the view, typically from a nib.
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return self.workouts.count
}
func setTableViewBackgroundGradient(topColor: UIColor, bottomColor: UIColor){
let gradientBackgroundColors = [topColor.CGColor, bottomColor.CGColor]
let gradientLocations = [0.0,1.0]
let gradientLayer = CAGradientLayer()
gradientLayer.colors = gradientBackgroundColors
gradientLayer.locations = gradientLocations
gradientLayer.frame = tableView.bounds
let backgroundView = UIView(frame: tableView.bounds)
backgroundView.layer.insertSublayer(gradientLayer, atIndex: 0)
tableView.backgroundView = backgroundView
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let workout = self.workouts[indexPath.row] as? Workout
let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as? WorkoutCell
cell!.textCellLabel?.text = workout?.title
cell!.backgroundColor = workout?.color
cell!.countLabel.text = "\(indexPath.row+1)"
cell!.selectionStyle = UITableViewCellSelectionStyle.None
cell!.backgroundColor = UIColor.clearColor()
return cell!
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "detailview"){
let cell = sender as? WorkoutCell
let indexPath = tableView.indexPathForCell(cell!)
let nvc = segue.destinationViewController as? UINavigationController
if let tmp = workouts[indexPath!.row] as? Workout{
let dvc = nvc?.topViewController as! DetailViewController
dvc.workout = tmp
}
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.tableView.contentInset = UIEdgeInsetsMake(0,0,55,0)
}
}
Related
I'm trying to create a drop-down menu. In this drop-down menu, I have a UIView which the user taps on to drop down a UITableView. In the process of creating it, I tried to change the separator color to clear. However, it's not working. I have tried settings it different colors all to no avail, but for some reason when I try to set its edge inset it works. Can someone help me out?
private var selectedBackgroundColor : UIColor = UIColor(red: 131/255, green: 43/255, blue: 205/255, alpha: 1.0)
private var unSelectedBackgroundColor : UIColor = UIColor(red: 178/255, green: 90/255, blue: 253/255, alpha: 1.0)
override init(frame: CGRect) {
super.init(frame: frame)
self.commonInitializer()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
self.commonInitializer()
}
private func commonInitializer() {
self.backgroundColor = self.unSelectedBackgroundColor
self.layer.cornerRadius = self.bounds.height/2
let shadowColor = UIColor(red: 0xC8, green: 0xC6, blue: 0xC6)
self.layer.applySketchShadow(color: shadowColor, alpha: 0.5, x: 0, y: 2, blur: 5, spread: 0)
self.itemTableView.frame = CGRect(x: 0, y: 0, width: 0, height: 0)
self.itemTableView.translatesAutoresizingMaskIntoConstraints = false
self.itemTableView.delegate = self
self.itemTableView.dataSource = self
self.itemTableView.showsVerticalScrollIndicator = false
self.itemTableView.separatorColor = UIColor.clear
self.itemTableView.backgroundColor = self.unSelectedBackgroundColor
}
override func didMoveToSuperview() {
self.superview?.addSubview(itemTableView)
self.superview?.bringSubviewToFront(itemTableView)
//Drop down table view constraints
self.itemTableView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
self.itemTableView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
self.itemTableView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
self.tableViewHeight = self.itemTableView.heightAnchor.constraint(equalToConstant: 0)
}
/**
Changes the drop down button view and table view to the selected color
*/
private func changeToSelectedBackgroundColor() {
self.backgroundColor = self.selectedBackgroundColor
self.itemTableView.backgroundColor = self.selectedBackgroundColor
}
/**
Changes only the drop down button view to the unselected color. Changes the table view to white
*/
private func changeToUnSelectedBackgroundColor() {
self.backgroundColor = self.unSelectedBackgroundColor
self.itemTableView.backgroundColor = UIColor.white
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = self.items[indexPath.row]
cell.backgroundColor = UIColor.clear
cell.textLabel?.textColor = UIColor.white
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.itemTableView.deselectRow(at: indexPath, animated: true)
self.retractDropDownList()
}
#objc func buttonTapped() {
self.flashLabel()
if isExtended {
self.retractDropDownList()
} else {
self.expandDropDownList()
}
}
private func expandDropDownList() {
isExtended = true
self.delegate?.dropDownViewExtended()
NSLayoutConstraint.deactivate([self.tableViewHeight])
self.tableViewHeight.constant = 150.0
NSLayoutConstraint.activate([
self.tableViewHeight])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.changeToSelectedBackgroundColor()
self.itemTableView.layoutIfNeeded()
self.layer.cornerRadius = 0.0
self.itemTableView.center.y += self.itemTableView.frame.height/2
}, completion: nil)
}
private func retractDropDownList() {
isExtended = false
self.delegate?.dropDownViewRetracted()
NSLayoutConstraint.deactivate([self.tableViewHeight])
self.tableViewHeight.constant = 0.0
NSLayoutConstraint.activate([
self.tableViewHeight])
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
self.changeToUnSelectedBackgroundColor()
self.itemTableView.center.y -= self.itemTableView.frame.height/2
self.itemTableView.layoutIfNeeded()
self.layer.cornerRadius = self.bounds.height/2
}, completion: nil)
}
}
I just realized that my table view is not working correctly, after checking my App on multiple devices. I am currently working on a View that contains a Scroll View at the top, and an TableView at the bottom.
When I was creating the View I was working with an Iphone XS Max as my testing device, and everything worked fine. However, when the device gets smaller the Table View starts to do weird things.
Thats what I want the table view to look like:
Table View on Iphone XS Max
On smaller devices the background color of the last table view cell is not green (what it should be according to code), instead it has the same color as the first cell.
When I scroll back to the top, the first cell has the color the last cell should have according to my code
Here is my cellForRowAt IndexPath
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "GruppenCell", for: indexPath) as! GroupCell
cell.bgView.backgroundColor = nil
cell.bgView.layer.cornerRadius = 10
cell.bgView.clipsToBounds = true
cell.selectionStyle = .none
if(indexPath.row == 0) {
cell.bgView.setGradientBackground(colorOne: UIColor.white
, colorTwo: KitaGruppen.Spatzen().color, bounds_object: cell.bgView)
cell.groupLabel!.text = "Spatzen"
cell.iconImageView?.image = UIImage(named: "SpatzIcon")
}
else if(indexPath.row == 1) {
cell.bgView.setGradientBackground(colorOne: UIColor.white
, colorTwo: KitaGruppen.Elefanten().color, bounds_object: cell.bgView)
cell.groupLabel!.text = "Elefanten"
cell.iconImageView?.image = UIImage(named: "elefantIcon")
}
else if(indexPath.row == 2) {
cell.bgView.setGradientBackground(colorOne: UIColor.white
, colorTwo: KitaGruppen.Mäuse().color, bounds_object: cell.bgView)
cell.groupLabel!.text = "Mäuse"
cell.iconImageView?.image = UIImage(named: "mouseIcon")
}
else if(indexPath.row == 3) {
cell.bgView.setGradientBackground(colorOne: UIColor.lightGray
, colorTwo: KitaGruppen.Pferde().color, bounds_object: cell.bgView)
cell.groupLabel!.text = "Pferde"
cell.iconImageView?.image = UIImage(named: "horseIcon")
print("Ich bin der Pferd Index")
}
else if(indexPath.row == 4) {
cell.bgView.setGradientBackground(colorOne: UIColor.lightGray
, colorTwo: KitaGruppen.Frösche().color, bounds_object: cell.bgView)
cell.groupLabel!.text = "Frösche"
cell.iconImageView?.image = UIImage(named: "FrogIcon")
}
else {
cell.bgView.setGradientBackground(colorOne: UIColor.lightGray
, colorTwo: UIColor.white, bounds_object: cell.bgView)
}
return cell
}
Here is my Struct for the colors
struct KitaGruppen {
struct Spatzen{
var name = "Spatzen"
var name_lower = "spatzen"
var color = #colorLiteral(red: 1, green: 0.871347487, blue: 0, alpha: 1)
}
struct Elefanten{
var name = "Elefanten"
var name_lower = "Elefanten"
var color = #colorLiteral(red: 0, green: 0.3798098862, blue: 1, alpha: 1)
}
struct Pferde{
var name = "Pferde"
var name_lower = "pferde"
var color = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1)
}
struct Frösche{
var name = "Frösche"
var name_lower = "frösche"
var color = #colorLiteral(red: 0.5412063003, green: 0.9987080693, blue: 0.2685243189, alpha: 1)
}
struct Mäuse{
var name = "Mäuse"
var name_lower = "Mäuse"
let color = #colorLiteral(red: 0.9411764741, green: 0.4980392158, blue: 0.3529411852, alpha: 1)
}
}
Here is my Cell Class
class GroupCell: UITableViewCell {
override func prepareForReuse() {
super.prepareForReuse()
self.iconImageView.image = nil
self.groupLabel.text = ""
self.bgView.setGradientBackground(colorOne: UIColor.white
, colorTwo: KitaGruppen.Spatzen().color, bounds_object: self.bgView)
}
I added the prepareForReuse Method to fix this error, but it did not have any affects.
I dont know if it is important, but here is my setGradientBackground Method:
func setGradientBackground(colorOne: UIColor, colorTwo: UIColor, bounds_object: UIView){
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds_object.bounds
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 1.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 0.0, y: 0.0)
layer.insertSublayer(gradientLayer, at: 0)
}
The weird thing is that the only cell data that has this bug is the gradient color. The text for the text label, and also the icons don't get mixed up at all.
Does anybody know any fix for this ?
Thanks for your help!
The issue could be caused by the fact that a new gradient layer is inserted every time setGradientBackground is called.
To avoid that check if the layer exists. If it exists update the colors otherwise create the new layer.
func setGradientBackground(colorOne: UIColor, colorTwo: UIColor, bounds_object: UIView){
if let gradientLayer = layer.sublayers?.first as? CAGradientLayer {
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
} else {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds_object.bounds
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 1.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 0.0, y: 0.0)
layer.insertSublayer(gradientLayer, at: 0)
}
}
Actually prepareForReuse() is redundant because you can set image and text in the last else scope. It makes sure that all UI elements are set to a defined state.
Add these two lines and delete the entire prepareForReuse() method in GroupCell.
else {
cell.bgView.setGradientBackground(colorOne: UIColor.lightGray
, colorTwo: UIColor.white, bounds_object: cell.bgView)
cell.iconImageView.image = nil
cell.groupLabel.text = ""
}
A better syntax than if - else if in this case is a switch
switch indexPath.row {
case 0:
cell.bgView.setGradientBackground(colorOne: UIColor.white
, colorTwo: KitaGruppen.Spatzen().color, bounds_object: cell.bgView)
cell.groupLabel!.text = "Spatzen"
cell.iconImageView?.image = UIImage(named: "SpatzIcon")
case 1:
cell.bgView.setGradientBackground(colorOne: UIColor.white
, colorTwo: KitaGruppen.Elefanten().color, bounds_object: cell.bgView)
cell.groupLabel!.text = "Elefanten"
cell.iconImageView?.image = UIImage(named: "elefantIcon")
...
default:
cell.bgView.setGradientBackground(colorOne: UIColor.lightGray
, colorTwo: UIColor.white, bounds_object: cell.bgView)
cell.iconImageView.image = nil
cell.groupLabel.text = ""
}
I have a UIView extension which makes a gradient background from two colours. I use this so I add a nice background to my custom tableView cells. But after the reuse, the colour is always wrong (unlike the data inside which is correct). It's not like a plain background colour, and all colors depend on the value from the fetched data. After reuse, the background is always random from the previously generated cells (and their backgrounds).
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as! TableViewCell
var imgTitle = ""
var color = UIColor()
let title = fetchedUV[indexPath.row].value
if title > 11 {
imgTitle = "flame"
color = UIColor.purple
cell.setGradientBackground(colorOne: .white, colorTwo: color)
} else if title >= 8 {
imgTitle = "sun-protection"
color = UIColor.red
cell.setGradientBackground(colorOne: .white, colorTwo: color)
} else if title >= 6 {
imgTitle = "sunbed"
color = UIColor.orange
cell.setGradientBackground(colorOne: .white, colorTwo: color)
} else if title >= 3 {
imgTitle = "sunglasses"
color = UIColor.yellow
cell.setGradientBackground(colorOne: .white, colorTwo: color)
} else {
imgTitle = "ok"
color = UIColor.green
cell.setGradientBackground(colorOne: .white, colorTwo: color)
}
colors.append(color)
let UVValue = String(describing: title)
cell.backgroundColor = UIColor.orange
cell.commonInit(imgTitle, title: UVValue, time: fetchedUV[indexPath.row].dateIso)
cell.logoImage.layer.cornerRadius = (cell.frame.height) / 2
cell.layer.cornerRadius = cell.frame.height/2
cell.layer.masksToBounds = true
//cell.setGradientBackground(colorOne: .white, colorTwo: color)
return cell
}
extension UIView {
func setGradientBackground(colorOne: UIColor, colorTwo: UIColor) {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
layer.insertSublayer(gradientLayer, at: 0)
}
}
Just for an Example try looking at this
extension UIView
{
//This func will add gradient backgroung
//Just sample one
func setGradientBackground()
{
//Colors
let colorTop = UIColor(red: 255.0/255.0, green: 149.0/255.0, blue: 0.0/255.0, alpha: 1.0).cgColor
let colorBottom = UIColor(red: 255.0/255.0, green: 94.0/255.0, blue: 58.0/255.0, alpha: 1.0).cgColor
//Set Gradient layer
let gradientLayer = CAGradientLayer()
//Colors
gradientLayer.colors = [ colorTop, colorBottom]
//Locations
gradientLayer.locations = [ 0.0, 1.0]
//Here is the main Play
//Set Layer name so can be identified while Dequeuing cell
gradientLayer.name = "layerName"
//Set bounds
gradientLayer.frame = self.layer.bounds
//Insert Layer
self.layer.addSublayer(gradientLayer)
}
}
Now in CellForRowAt of TableView
//Setting cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
//Get all the sublayers of cell
for sublayer in cell.layer.sublayers!
{
//Check that sublayer is Already Added or not
if sublayer.name == "layerName"
{
//Sublayer already added
//Print already Added
print("Cell Deque again")
}
else
{
//Sublayer is not added yet
//Time to add Gradient Background
cell.setGradientBackground()
print("Layer Added")
}
}
//setting title
cell.textLabel?.text = items[indexPath.section][indexPath.row]
return cell
}
Hope it Helps , You can Name a layer that is being added as SubLayer and when Adding it to Cell as it gets Deque again and again so you must see that layer is not override on previous added layer
I had find and remove the previously added layer (the CAGradientLayer because it can remove any other layer as well). Do the checks and add another layer if its needed. I also changed the function so the layer now has a name. (thanks to iOS Geek for the suggestion)
for sublayer in cell.layer.sublayers! {
if let _ = sublayer as? CAGradientLayer {
if sublayer.name == name {
print("Cell deque again")
} else {
sublayer.removeFromSuperlayer()
cell.setGradientBackground0(colorOne: .white, colorTwo: color, name: name)
}
} else {
cell.setGradientBackground0(colorOne: .white, colorTwo: color, name: name)
}
}
extension UIView {
func setGradientBackground0(colorOne: UIColor, colorTwo: UIColor, name: String) {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
gradientLayer.name = name
layer.insertSublayer(gradientLayer, at: 0)
}
}
I'll leave this just in case.
I am developing an application for an online forum with DTCoreText to display thread replies that parsed from BBCode to HTML with text and images inside custom cells in a UITableView. I use interface builder to build my prototype cell and link it to my custom cell class using outlets. Texts are displaying correctly but the images are not loading and leaves a empty space inside the cell view. Heres my view controller and cell class code
My View Controller:
//
import UIKit
import NVActivityIndicatorView
class ContentViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
//MARK: Properties
var threadIdReceived: String = ""
var channelNow: String = ""
var isRated: Bool = false
var pageNow: Int = 1
var convertedText: String = ""
var op = OP(t: "",n: "",l: "",c: "",cH: "",a: "",d: "",gd: "",b: "",ge: "",ch: "")
var comments = [Replies]()
var replyCount = 1
#IBOutlet weak var contentTableView: UITableView!
#IBOutlet weak var pageButton: UIBarButtonItem!
#IBOutlet weak var goodCount: UIBarButtonItem!
#IBOutlet weak var badCount: UIBarButtonItem!
#IBOutlet weak var prevButton: UIBarButtonItem!
#IBOutlet weak var nextButton: UIBarButtonItem!
let backgroundIndicator = NVActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height),type: .ballPulseSync,padding: 175)
//HKGalden API (NOT included in GitHub repo)
var api = HKGaldenAPI()
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.tintColor = UIColor.white
self.navigationController?.navigationBar.isTranslucent = true
contentTableView.delegate = self
contentTableView.dataSource = self
backgroundIndicator.startAnimating()
self.view.addSubview(backgroundIndicator)
self.prevButton.isEnabled = false
self.pageButton.title = "第" + String(pageNow) + "頁"
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
contentTableView.isHidden = true
api.fetchContent(postId: threadIdReceived, pageNo: String(pageNow), completion: {
[weak self] op,comments,error in
if (error == nil) {
self?.op = op
self?.comments = comments
self?.title = op.title
self?.goodCount.title = op.good
self?.badCount.title = op.bad
self?.contentTableView.reloadData()
self?.backgroundIndicator.isHidden = true
self?.contentTableView.isHidden = false
self?.contentTableView.tableFooterView = UIView()
}
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (comments.count) + 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ContentTableViewCell", for: indexPath) as! ContentTableViewCell
if(indexPath.row == 0) {
cell.configureOP(opData: op)
}
else {
cell.configureReply(comments: comments, indexPath: indexPath,pageNow: pageNow)
}
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
#IBAction func changePage(_ sender: UIBarButtonItem) {
switch (sender.tag) {
case 0:
contentTableView.isHidden = true
backgroundIndicator.isHidden = false
self.pageNow -= 1
self.pageButton.title = "第" + String(self.pageNow) + "頁"
self.api.fetchContent(postId: threadIdReceived, pageNo: String(pageNow), completion: {
[weak self] op,comments,error in
if (error == nil) {
self?.op = op
self?.comments = comments
self?.title = op.title
self?.goodCount.title = op.good
self?.badCount.title = op.bad
self?.contentTableView.reloadData()
self?.backgroundIndicator.isHidden = true
self?.contentTableView.isHidden = false
self?.contentTableView.tableFooterView = UIView()
}
})
case 1:
self.prevButton.isEnabled = true
contentTableView.isHidden = true
backgroundIndicator.isHidden = false
self.pageNow += 1
self.pageButton.title = "第" + String(self.pageNow) + "頁"
self.api.fetchContent(postId: threadIdReceived, pageNo: String(pageNow), completion: {
[weak self] op,comments,error in
if (error == nil) {
self?.op = op
self?.comments = comments
self?.title = op.title
self?.goodCount.title = op.good
self?.badCount.title = op.bad
self?.contentTableView.reloadData()
self?.backgroundIndicator.isHidden = true
self?.contentTableView.isHidden = false
self?.contentTableView.tableFooterView = UIView()
}
})
default:
print("nothing")
}
}
//MARK: Private Functions
private func barTintColorChanger(channelId: String) {
switch channelId {
case "bw":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 72/255, green: 125/255, blue: 174/255, alpha: 1)
case "et":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 152/255, green: 85/255, blue: 159/255, alpha: 1)
case "ca":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 33/255, green: 136/255, blue: 101/255, alpha: 1)
case "fn":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 33/255, green: 136/255, blue: 101/255, alpha: 1)
case "gm":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 37/255, green: 124/255, blue: 201/255, alpha: 1)
case "ap":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 41/255, green: 145/255, blue: 185/255, alpha: 1)
case "it":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 94/255, green: 106/255, blue: 125/255, alpha: 1)
case "mp":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 88/255, green: 100/255, blue: 174/255, alpha: 1)
case "sp":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 152/255, green: 64/255, blue: 81/255, alpha: 1)
case "lv":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 196/255, green: 53/255, blue: 94/255, alpha: 1)
case "sy":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 127/255, green: 112/255, blue: 106/255, alpha: 1)
case "ed":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 65/255, green: 143/255, blue: 66/255, alpha: 1)
case "tm":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 190/255, green: 71/255, blue: 30/255, alpha: 1)
case "tr":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 97/255, green: 118/255, blue: 83/255, alpha: 1)
case "an":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 171/255, green: 80/255, blue: 159/255, alpha: 1)
case "to":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 148/255, green: 95/255, blue: 50/255, alpha: 1)
case "mu":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 88/255, green: 95/255, blue: 202/255, alpha: 1)
case "vi":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 121/255, green: 78/255, blue: 126/255, alpha: 1)
case "dc":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 56/255, green: 102/255, blue: 118/255, alpha: 1)
case "st":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 128/255, green: 113/255, blue: 143/255, alpha: 1)
case "ts":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 172/255, green: 48/255, blue: 66/255, alpha: 1)
case "mb":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 124/255, green: 89/255, blue: 196/255, alpha: 1)
case "ia":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 132/255, green: 169/255, blue: 64/255, alpha: 1)
case "ac":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 150/255, green: 75/255, blue: 112/255, alpha: 1)
case "ep":
self.navigationController?.navigationBar.barTintColor = UIColor(red: 152/255, green: 112/255, blue: 93/255, alpha: 1)
default:
self.navigationController?.navigationBar.barTintColor = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1)
}
}
}
And heres my cell class:
import UIKit
import Kingfisher
import DTCoreText
class ContentTableViewCell: UITableViewCell, DTAttributedTextContentViewDelegate, DTLazyImageViewDelegate {
//MARK: Properties
#IBOutlet weak var userNameLabel: UILabel!
#IBOutlet weak var userLevelLabel: UILabel!
#IBOutlet weak var userAvatarImageView: UIImageView!
#IBOutlet weak var replyCountLabel: UILabel!
#IBOutlet weak var dateLabel: UILabel!
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var contentTextView: DTAttributedTextContentView!
let attributedOptions: NSDictionary = [
NSAttributedString.DocumentAttributeKey.documentType: NSAttributedString.DocumentType.html,
NSAttributedString.DocumentAttributeKey.characterEncoding: String.Encoding.utf8,
DTDefaultFontFamily: "Helvetica Neue",
DTDefaultFontSize: 15,
DTMaxImageSize: CGSize(width:280,height:450)
]
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
contentTextView.shouldDrawImages = false
contentTextView.delegate = self as DTAttributedTextContentViewDelegate
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func attributedTextContentView(_ attributedTextContentView: DTAttributedTextContentView!, viewFor attachment: DTTextAttachment!, frame: CGRect) -> UIView! {
if attachment is DTImageTextAttachment {
let imageView = DTLazyImageView(frame: frame)
imageView.contentView = contentTextView
imageView.delegate = self as DTLazyImageViewDelegate
//url for deferred loading
imageView.url = attachment.contentURL
imageView.shouldShowProgressiveDownload = true
return imageView
}
return nil
}
func lazyImageView(_ lazyImageView: DTLazyImageView!, didChangeImageSize size: CGSize) {
let url = lazyImageView.url
let pred = NSPredicate(format: "contentURL == %#",url! as CVarArg)
let array = self.contentTextView.layoutFrame.textAttachments(with: pred)
for _ in (array?.enumerated())! {
let element = DTTextAttachment()
element.originalSize = size
element.displaySize = size
}
contentTextView.layouter = nil
contentTextView.relayoutText()
}
func configureOP(opData: OP) {
userNameLabel.text = opData.name
if(opData.gender == "male") {
userNameLabel.textColor = UIColor(red:0.68, green:0.78, blue:0.81, alpha:1.0)
}
else {
userNameLabel.textColor = UIColor(red:1.00, green:0.41, blue:0.38, alpha:1.0)
}
if(opData.level == "lv1") {
userLevelLabel.text = "普通會然"
userLevelLabel.backgroundColor = UIColor.darkGray
}
else if (opData.level == "lv2") {
userLevelLabel.text = "迷の存在"
userLevelLabel.backgroundColor = UIColor(red:0.55, green:0.00, blue:0.00, alpha:1.0)
}
else if (opData.level == "lv3") {
userLevelLabel.text = "肉務腸"
userLevelLabel.backgroundColor = UIColor(red:0.47, green:0.87, blue:0.47, alpha:1.0)
}
else if (opData.level == "lv4") {
userLevelLabel.text = "唉屎"
userLevelLabel.backgroundColor = UIColor(red:0.00, green:1.00, blue:1.00, alpha:1.0)
}
let avatarURL = URL(string: "https://hkgalden.com" + opData.avatar)
if (opData.avatar == "") {
userAvatarImageView.image = UIImage(named: "DefaultAvatar")
}
else {
userAvatarImageView.kf.setImage(with: avatarURL)
}
//remove abundant </img> tag
opData.contentHTML = opData.contentHTML.replacingOccurrences(of: "</img>", with: "")
//print(opData.contentHTML)
let contentData = opData.contentHTML.data(using: .utf8)
let contentAttr = NSAttributedString.init(htmlData: contentData, options: attributedOptions as! [AnyHashable : Any], documentAttributes: nil)
//print(contentAttr)
contentTextView.attributedString = contentAttr
replyCountLabel.text = "OP"
dateLabel.text = opData.date
}
func configureReply(comments: [Replies],indexPath: IndexPath,pageNow: Int) {
userNameLabel.text = comments[indexPath.row - 1].name
if(comments[indexPath.row - 1].gender == "male") {
userNameLabel.textColor = UIColor(red:0.68, green:0.78, blue:0.81, alpha:1.0)
}
else {
userNameLabel.textColor = UIColor(red:1.00, green:0.41, blue:0.38, alpha:1.0)
}
if(comments[indexPath.row - 1].level == "lv1") {
userLevelLabel.text = "普通會然"
userLevelLabel.backgroundColor = UIColor.darkGray
}
else if (comments[indexPath.row - 1].level == "lv2") {
userLevelLabel.text = "迷の存在"
userLevelLabel.backgroundColor = UIColor(red:0.55, green:0.00, blue:0.00, alpha:1.0)
}
else if (comments[indexPath.row - 1].level == "lv3") {
userLevelLabel.text = "肉務腸"
userLevelLabel.backgroundColor = UIColor(red:0.47, green:0.87, blue:0.47, alpha:1.0)
}
else if (comments[indexPath.row - 1].level == "lv4") {
userLevelLabel.text = "唉屎"
userLevelLabel.backgroundColor = UIColor(red:0.00, green:1.00, blue:1.00, alpha:1.0)
}
let avatarURL = URL(string: "https://hkgalden.com" + comments[indexPath.row - 1].avatar)
if (comments[indexPath.row - 1].avatar == "") {
userAvatarImageView.image = UIImage(named: "DefaultAvatar")
}
else {
userAvatarImageView.kf.setImage(with: avatarURL)
}
replyCountLabel.text = "#" + String(25 * (pageNow - 1) + indexPath.row)
dateLabel.text = comments[indexPath.row - 1].date
let contentData = comments[indexPath.row - 1].contentHTML.data(using: .utf8)
let contentAttr = NSAttributedString.init(htmlData: contentData, options: attributedOptions as! [AnyHashable : Any], documentAttributes: nil)
//print(contentAttr)
contentTextView.attributedString = contentAttr
}
}
Try this category - it works for me
extension UIImageView {
public func imageFromUrl(url: URL?) {
if let url = url {
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else { return }
DispatchQueue.main.async { [weak self] in
self?.image = UIImage(data: data)
}
}
task.resume()
}
}
}
I have an IconView class that I use as a custom image for a Google Maps marker. All of the print statements show that the code is correctly executing. However, the "12:08" UILabel in circleView keeps on growing and shrinking (i.e. twitching). I can't figure out what the problem might be. I've tried manually setting the the font in the completion block, commenting out the adjustsFontSizeToFitWidth, changing the circleView to a UIButton.
import UIKit
class IconView: UIView {
var timeLabel: UILabel!
var circleView: UIView!
var clicked: Bool!
//constants
let circleViewWidth = 50.0
let circleViewHeight = 50.0
override init(frame:CGRect) {
super.init(frame : frame)
self.backgroundColor = UIColor(red: 47/255, green: 49/255, blue: 53/255, alpha: 0.0)
clicked = false
if !clicked {
//MAIN CIRCLE
print("init circle view")
circleView = UIView(frame: CGRect(x:0, y:0, width:circleViewWidth, height:circleViewHeight))
circleView.backgroundColor = UIColor(red: 47/255, green: 49/255, blue: 53/255, alpha: 1.0)
circleView.layer.cornerRadius = circleView.frame.size.height / 2.0
circleView.layer.masksToBounds = true
self.addSubview(circleView)
timeLabel = UILabel(frame: CGRect(x: 0, y: 0, width: circleViewWidth, height: circleViewHeight/3.0))
timeLabel.center = circleView.center
timeLabel.text = "12:08"
timeLabel.textAlignment = .center
timeLabel.textColor = .white
timeLabel.numberOfLines = 0
timeLabel.font = UIFont.systemFont(ofSize: 11)
timeLabel.font = UIFont.boldSystemFont(ofSize: 11)
timeLabel.adjustsFontSizeToFitWidth = true
circleView.addSubview(timeLabel)
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
let iconView = marker.iconView as! IconView
print("going to start animating")
if !iconView.clicked {
UIView.animate(withDuration: 0.2, animations: {
print("making this bigger now")
iconView.circleView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
})
{ (finished:Bool) -> Void in
print("DONE")
iconView.clicked = true
}
}
return true
}