I want to use TTTAttributedLabel to detect the link of the text in the Label of UITableViewCell, but it doesn't work. I'm using swift with iOS8. below is UITableViewCell code:
class StoryTableViewCell: UITableViewCell, TTTAttributedLabelDelegate {
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
// Link properties
let textLabel = self.descriptionLabel
let linkColor = UIColor(red: 0.203, green: 0.329, blue: 0.835, alpha: 1)
let linkActiveColor = UIColor.blackColor()
if (textLabel is TTTAttributedLabel) {
var label = textLabel as TTTAttributedLabel
label.linkAttributes = [NSForegroundColorAttributeName : linkColor]
label.activeLinkAttributes = [NSForegroundColorAttributeName : linkActiveColor]
label.enabledTextCheckingTypes = NSTextCheckingType.Link.toRaw()
label.delegate = self
}
}
}
I think you have not configured your custom cell correctly.
First at your customCell declare and connect your IBOutlet-s. Select your textLabel and add its class to TTTAttributedLabel. Your custom cell should look like this:
class StoryTableViewCell: UITableViewCell {
#IBOutlet weak var textLabel: TTTAttributedLabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Second you need to add the TTTAttributedLabelDelegate at the class where you are using the tableView datasource and delegate.
Then under cellForRowAtIndexPath
var cell: StoryTableViewCell = tableView.dequeueReusableCellWithIdentifier("yourCellIdentifier") as StoryTableViewCell
let linkColor = UIColor(red: 0.203, green: 0.329, blue: 0.835, alpha: 1)
let linkActiveColor = UIColor.blackColor()
cell.textLabel.delegate = self
cell.textLabel.linkAttributes = [kCTForegroundColorAttributeName : linkColor]
cell.textLabel.activeLinkAttributes = [kCTForegroundColorAttributeName : linkActiveColor]
cell.textLabel.enabledTextCheckingTypes = NSTextCheckingType.Link.rawValue
Then if you have methods that need to be executed from TTTAttributedLabelDelegate add them and do your calculations.
Hope it helps
If you've set TTTAttributedLabel as the class of your UILabel, within a nib or the storyboard, make sure User Interaction Enabled is set to true, as be default a UILabel will have user interaction disabled.
let linkColor = UIColor.blueColor()
let linkActiveColor = UIColor.greenColor()
textLabel.delegate = self
textLabel.linkAttributes = [kCTForegroundColorAttributeName : linkColor.CGColor,kCTUnderlineStyleAttributeName : NSNumber(bool: true)]
textLabel.activeLinkAttributes = [NSForegroundColorAttributeName : linkActiveColor]
textLabel.enabledTextCheckingTypes = NSTextCheckingType.Link.rawValue
swift 4.2
label.enabledTextCheckingTypes = NSTextCheckingResult.CheckingType.link.rawValue | NSTextCheckingResult.CheckingType.phoneNumber.rawValue
Nothing works for me finally i put below code in TTTAttributedLabel.m in commonInit() method
self.enabledTextCheckingTypes = NSTextCheckingTypeLink;
Related
I've learned that we can change the UISwitch button appearance in its "on" state,
but is it also possible to change the color of the UISwitch in the "off" state?
My solution with #swift2:
let onColor = _your_on_state_color
let offColor = _your_off_state_color
let mSwitch = UISwitch(frame: CGRect.zero)
mSwitch.on = true
/*For on state*/
mSwitch.onTintColor = onColor
/*For off state*/
mSwitch.tintColor = offColor
mSwitch.layer.cornerRadius = mSwitch.frame.height / 2.0
mSwitch.backgroundColor = offColor
mSwitch.clipsToBounds = true
Result:
Try using this
yourSwitch.backgroundColor = [UIColor whiteColor];
youSwitch.layer.cornerRadius = 16.0;
All thanks to #Barry Wyckoff.
You can use the tintColor property on the switch.
switch.tintColor = [UIColor redColor]; // the "off" color
switch.onTintColor = [UIColor greenColor]; // the "on" color
Note this requires iOS 5+
Swift IBDesignable
import UIKit
#IBDesignable
class UISwitchCustom: UISwitch {
#IBInspectable var OffTint: UIColor? {
didSet {
self.tintColor = OffTint
self.layer.cornerRadius = 16
self.backgroundColor = OffTint
}
}
}
set class in Identity inspector
change color from Attributes inspector
Output
Here's a pretty good trick: you can just reach right into the UISwitch's subview that draws its "off" background, and change its background color. This works a lot better in iOS 13 than it does in iOS 12:
if #available(iOS 13.0, *) {
self.sw.subviews.first?.subviews.first?.backgroundColor = .green
} else if #available(iOS 12.0, *) {
self.sw.subviews.first?.subviews.first?.subviews.first?.backgroundColor = .green
}
Working 100% IOS 13.0 and Swift 5.0 switch both state color set same #ios13 #swift #swift5
#IBOutlet weak var switchProfile: UISwitch!{
didSet{
switchProfile.onTintColor = .red
switchProfile.tintColor = .red
switchProfile.subviews[0].subviews[0].backgroundColor = .red
}
}
The Best way to manage background color & size of UISwitch
For now it's Swift 2.3 code
import Foundation
import UIKit
#IBDesignable
class UICustomSwitch : UISwitch {
#IBInspectable var OnColor : UIColor! = UIColor.blueColor()
#IBInspectable var OffColor : UIColor! = UIColor.grayColor()
#IBInspectable var Scale : CGFloat! = 1.0
override init(frame: CGRect) {
super.init(frame: frame)
self.setUpCustomUserInterface()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setUpCustomUserInterface()
}
func setUpCustomUserInterface() {
//clip the background color
self.layer.cornerRadius = 16
self.layer.masksToBounds = true
//Scale down to make it smaller in look
self.transform = CGAffineTransformMakeScale(self.Scale, self.Scale);
//add target to get user interation to update user-interface accordingly
self.addTarget(self, action: #selector(UICustomSwitch.updateUI), forControlEvents: UIControlEvents.ValueChanged)
//set onTintColor : is necessary to make it colored
self.onTintColor = self.OnColor
//setup to initial state
self.updateUI()
}
//to track programatic update
override func setOn(on: Bool, animated: Bool) {
super.setOn(on, animated: true)
updateUI()
}
//Update user-interface according to on/off state
func updateUI() {
if self.on == true {
self.backgroundColor = self.OnColor
}
else {
self.backgroundColor = self.OffColor
}
}
}
Swift 5:
import UIKit
extension UISwitch {
func set(offTint color: UIColor ) {
let minSide = min(bounds.size.height, bounds.size.width)
layer.cornerRadius = minSide / 2
backgroundColor = color
tintColor = color
}
}
Should you need other switches around your app, it might be also a good idea implementing #LongPham's code inside a custom class.
As others have pointed out, for the "off" state you'll need to change the background colour as well, since the default is transparent.
class MySwitch: UISwitch {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Setting "on" state colour
self.onTintColor = UIColor.green
// Setting "off" state colour
self.tintColor = UIColor.red
self.layer.cornerRadius = self.frame.height / 2
self.backgroundColor = UIColor.red
}
}
Swift 4 easiest and fastest way to get it in 3 steps:
// background color is the color of the background of the switch
switchControl.backgroundColor = UIColor.white.withAlphaComponent(0.9)
// tint color is the color of the border when the switch is off, use
// clear if you want it the same as the background, or different otherwise
switchControl.tintColor = UIColor.clear
// and make sure that the background color will stay in border of the switch
switchControl.layer.cornerRadius = switchControl.bounds.height / 2
If you manually change the size of the switch (e.g., by using autolayout), you will have to update the switch.layer.cornerRadius too, e.g., by overriding layoutSubviews and after calling super updating the corner radius:
override func layoutSubviews() {
super.layoutSubviews()
switchControl.layer.cornerRadius = switchControl.bounds.height / 2
}
In Swift 4+:
off state:
switch.tintColor = UIColor.blue
on state:
switch.onTintColor = UIColor.red
The UISwitch offTintColor is transparent, so whatever is behind the switch shows through. Therefore, instead of masking the background color, it suffices to draw a switch-shaped image behind the switch (this implementation assumes that the switch is positioned by autolayout):
func putColor(_ color: UIColor, behindSwitch sw: UISwitch) {
guard sw.superview != nil else {return}
let onswitch = UISwitch()
onswitch.isOn = true
let r = UIGraphicsImageRenderer(bounds:sw.bounds)
let im = r.image { ctx in
onswitch.layer.render(in: ctx.cgContext)
}.withRenderingMode(.alwaysTemplate)
let iv = UIImageView(image:im)
iv.tintColor = color
sw.superview!.insertSubview(iv, belowSubview: sw)
iv.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
iv.topAnchor.constraint(equalTo: sw.topAnchor),
iv.bottomAnchor.constraint(equalTo: sw.bottomAnchor),
iv.leadingAnchor.constraint(equalTo: sw.leadingAnchor),
iv.trailingAnchor.constraint(equalTo: sw.trailingAnchor),
])
}
[But see now my other answer.]
2020 As of Xcode 11.3.1 & Swift 5
Here's the simplest way I've found of doing setting the UISwitch off-state colour with one line of code. Writing this here since this page is what came up first when I was looking and the other answers didn't help.
This is if I wanted to set the off state to be red, and can be added to the viewDidLoad() function:
yourSwitchName.subviews[0].subviews[0].backgroundColor = UIColor.red
Note - what this is actually doing is setting the background colour of the switch. This may influence the colour of the switch in the on-state too (though for me this wasn't a problem since I wanted the on and off state to be the same colour).
A solution for this:
Simply tie in the colours with an 'if else' statement inside your IBAction. If the switch is off, colour the background red. If the switch is on, leave the background clear so your chosen 'on' colour will display properly.
This goes inside the switch IBAction.
if yourSwitch.isOn == false {
yourSwitch.subviews[0].subviews[0].backgroundColor = UIColor.red
} else {
yourSwitch.subviews[0].subviews[0].backgroundColor = UIColor.clear
}
I found some behaviour where, upon the app resuming from background, the switch background would return to clear. To remedy this problem I simply added in the following code to set the colour every time the app comes to the foreground:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
NotificationCenter.default.addObserver(
self,
selector: #selector(applicationWillEnterForeground(_:)),
name: UIApplication.willEnterForegroundNotification,
object: nil)
}
#objc func applicationWillEnterForeground(_ notification: NSNotification) {
yourSwitch.subviews[0].subviews[0].backgroundColor = UIColor.red
yourSwitch.subviews[0].subviews[0].backgroundColor = UIColor.red
}
Seems simpler than the other answers. Hope that helps!
More safe way in Swift 3 without magical 16pt values:
class ColoredBackgroundSwitch: UISwitch {
var offTintColor: UIColor {
get {
return backgroundColor ?? UIColor.clear
}
set {
backgroundColor = newValue
}
}
override func layoutSubviews() {
super.layoutSubviews()
let minSide = min(frame.size.height, frame.size.width)
layer.cornerRadius = ceil(minSide / 2)
}
}
objective c category to use on any UISwitch in project using code or storyboard:
#import <UIKit/UIKit.h>
#interface UISwitch (SAHelper)
#property (nonatomic) IBInspectable UIColor *offTint;
#end
implementation
#import "UISwitch+SAHelper.h"
#implementation UISwitch (SAHelper)
#dynamic offTint;
- (void)setOffTint:(UIColor *)offTint {
self.tintColor = offTint; //comment this line to hide border in off state
self.layer.cornerRadius = 16;
self.backgroundColor = offTint;
}
#end
XCode 11, Swift 5
I don't prefer using subViews, cause you never know when apple gonna change the hierarchy.
so I use mask view instead.
it works with iOS 12, iOS 13
private lazy var settingSwitch: UISwitch = {
let swt: UISwitch = UISwitch()
// set border color when isOn is false
swt.tintColor = .cloudyBlueTwo
// set border color when isOn is true
swt.onTintColor = .greenishTeal
// set background color when isOn is false
swt.backgroundColor = .cloudyBlueTwo
// create a mask view to clip background over the size you expected.
let maskView = UIView(frame: swt.frame)
maskView.backgroundColor = .red
maskView.layer.cornerRadius = swt.frame.height / 2
maskView.clipsToBounds = true
swt.mask = maskView
// set the scale to your expectation, here is around height: 34, width: 21.
let scale: CGFloat = 2 / 3
swt.transform = CGAffineTransform(scaleX: scale, y: scale)
swt.addTarget(self, action: #selector(switchOnChange(_:)), for: .valueChanged)
return swt
}()
#objc
func switchOnChange(_ sender: UISwitch) {
if sender.isOn {
// set background color when isOn is true
sender.backgroundColor = .greenishTeal
} else {
// set background color when isOn is false
sender.backgroundColor = .cloudyBlueTwo
}
}
I tested on IOS 14, set background as off color and onTintColor as On and works:
uiSwitch.onTintColor = UIColor.blue
uiSwitch.backgroundColor = UIColor.red
XCode 11, Swift 4.2
Starting with Matt's solution I added it to a custom, IBDesignable control. There is a timing issue in that didMoveToSuperview() is called before the offTintColor is set that needed to be handled.
#IBDesignable public class UISwitchCustom: UISwitch {
var switchMask: UIImageView?
private var observers = [NSKeyValueObservation]()
#IBInspectable dynamic var offTintColor : UIColor! = UIColor.gray {
didSet {
switchMask?.tintColor = offTintColor
}
}
override init(frame: CGRect) {
super.init(frame: frame)
initializeObservers()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initializeObservers()
}
private func initializeObservers() {
observers.append(observe(\.isHidden, options: [.initial]) {(model, change) in
self.switchMask?.isHidden = self.isHidden
})
}
override public func didMoveToSuperview() {
addOffColorMask(offTintColor)
super.didMoveToSuperview()
}
private func addOffColorMask(_ color: UIColor) {
guard self.superview != nil else {return}
let onswitch = UISwitch()
onswitch.isOn = true
let r = UIGraphicsImageRenderer(bounds:self.bounds)
let im = r.image { ctx in
onswitch.layer.render(in: ctx.cgContext)
}.withRenderingMode(.alwaysTemplate)
let iv = UIImageView(image:im)
iv.tintColor = color
self.superview!.insertSubview(iv, belowSubview: self)
iv.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
iv.topAnchor.constraint(equalTo: self.topAnchor),
iv.bottomAnchor.constraint(equalTo: self.bottomAnchor),
iv.leadingAnchor.constraint(equalTo: self.leadingAnchor),
iv.trailingAnchor.constraint(equalTo: self.trailingAnchor),
])
switchMask = iv
switchMask?.isHidden = self.isHidden
}
}
all I finally used transform and layer.cornerRadius too.
But I have added translation to it to be center.
private func setSwitchSize() {
let iosSwitchSize = switchBlockAction.bounds.size
let requiredSwitchSize = ...
let transform = CGAffineTransform(a: requiredSwitchSize.width / iosSwitchSize.width, b: 0,
c: 0, d: requiredSwitchSize.height / iosSwitchSize.height,
tx: (requiredSwitchSize.width - iosSwitchSize.width) / 2.0,
ty: (requiredSwitchSize.height - iosSwitchSize.height) / 2.0)
switchBlockAction.layer.cornerRadius = iosSwitchSize.height / 2.0
switchBlockAction.transform = transform
}
And I did use backgroundColor and tintColor in designer.
Hope it helps.
I am trying to build an app which has object of Items and a controller for it which is called ItemsController. Also on my screen I suppose to have a table view and a button on it. The functionality of button is when it is clicked it needs to check favoriteItems array in ItemsController if it is found in that array remove element, if it isn't found there then append it to array. Operations for remove and append good but unfortunately all cells are not working together. They creates their own favoriteItems array.
To achieve this I tried to make ItemsController to be a singleton. I changed class to a struct and called ItemsController.sharedInstance everywhere. It actually solved a lot of my problem and I believe that the source I learnt this is not wrong about it. But why my tableview cells doesn't use ItemsController's favoriteItems array instead create theirs?
struct ItemsController {
var favoriteItems = [Items]()
static var sharedInstance = ItemsController()
init(){
itemsArray = [...items...]
}
}
class TableViewCell: UITableViewCell {
#IBOutlet weak var favoriteButton: UIButton!
let buttonFirstColor : UIColor = UIColor.clear
let buttonSecondColor : UIColor = UIColor(red: 224/255.0, green: 74/255.0, blue: 94/255.0, alpha: 1.0)
var itemsController = ItemsController.sharedInstance
var itemDedicated = Items(name: "", pic: "", aciklama: "")
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
favoriteButton.layer.cornerRadius = 0.5 * favoriteButton.bounds.size.width
favoriteButton.backgroundColor = UIColor.clear
favoriteButton.layer.borderColor = UIColor(red: 224/255.0, green: 74/255.0, blue: 94/255.0, alpha: 1.0).cgColor
favoriteButton.layer.borderWidth = 4.0
favoriteButton.clipsToBounds = true
setFavoriteButton()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func favoriteButtonClicked(_ sender: Any) {
var favoriteFound = false
for items in itemsController.favoriteItems{
if(items.name == itemDedicated.name){
favoriteFound = true }
}
if(favoriteFound){
itemsController.favoriteItems.remove(at: itemsController.favoriteItems.index(of: itemDedicated)!)
} else {
itemsController.favoriteItems.append(itemDedicated)
}
setFavoriteButton()
}
private func setFavoriteButton(){
var favoriteFound = false
for items in itemsController.favoriteItems{
if(items.name == itemDedicated.name){
favoriteFound = true }
}
if(favoriteFound){
favoriteButton.backgroundColor = buttonSecondColor
favoriteButton.setTitleColor(buttonFirstColor, for: .normal)
} else {
favoriteButton.backgroundColor = buttonFirstColor
favoriteButton.setTitleColor(buttonFirstColor, for: .normal)
}
}
}
I have created a custom View Class that inherits from GADNativeContentAdView Class. When I receive an advertisement and the delegate is called, I fill my custom view with the data as shown below.
Everything looks fine but the problem is that it is not clickable at all. I tried to set the actionbutton userinteraction to false, but still won't work.
I also tried to register using following:
-(void)registerAdView:(UIView *)adView
clickableAssetViews:(NSDictionary *)clickableAssetViews
nonclickableAssetViews:
(NSDictionary *)nonclickableAssetViews;
Any idea how to get it to work?
- (void)setNativeContent:(GADNativeContentAd *)nativeContent
{
self.nativeContentAd = nativeContent;
headlineLabel.text = nativeContent.headline;
bodyLabel.text = nativeContent.body;
advertiserImage.image = ((GADNativeAdImage *)nativeContent.images.firstObject).image;
[actionButton setTitle:nativeContent.callToAction forState:UIControlStateNormal];
if (nativeContent.logo && nativeContent.logo.image)
{
advertiserLogo.image = nativeContent.logo.image;
}
else
{
advertiserLogo.image = advertiserImage.image;
}
NSDictionary *clickableArea = #{GADNativeContentHeadlineAsset:headlineLabel, GADNativeContentImageAsset:advertiserImage, GADNativeContentCallToActionAsset:actionButton};
NSDictionary *nonClickableArea = #{GADNativeContentBodyAsset:bodyLabel};
[nativeContent registerAdView:self clickableAssetViews:clickableArea nonclickableAssetViews:nonClickableArea];
}
I finally figured out a way to make the entire native ad clickable without using a .xib. I subclassed GADNativeContentAdView and created a tappableOverlay view that I assigned to an unused asset view in its superclass. In this case, it was the callToActionView. Then I used the not-so-documented GADNativeContentAd.registerAdView() method:
- (void)registerAdView:(UIView *)adView
clickableAssetViews:(NSDictionary<GADNativeContentAdAssetID, UIView *> *)clickableAssetViews
nonclickableAssetViews: (NSDictionary<GADNativeContentAdAssetID, UIView *> *)nonclickableAssetViews;
Here's a Swift 4 example:
class NativeContentAdView: GADNativeContentAdView {
var nativeAdAssets: NativeAdAssets?
private let myImageView: UIImageView = {
let myImageView = UIImageView()
myImageView.translatesAutoresizingMaskIntoConstraints = false
myImageView.contentMode = .scaleAspectFill
myImageView.clipsToBounds = true
return myImageView
}()
private let myHeadlineView: UILabel = {
let myHeadlineView = UILabel()
myHeadlineView.translatesAutoresizingMaskIntoConstraints = false
myHeadlineView.numberOfLines = 0
myHeadlineView.textColor = .black
return myHeadlineView
}()
private let tappableOverlay: UIView = {
let tappableOverlay = UIView()
tappableOverlay.translatesAutoresizingMaskIntoConstraints = false
tappableOverlay.isUserInteractionEnabled = true
return tappableOverlay
}()
private let adAttribution: UILabel = {
let adAttribution = UILabel()
adAttribution.translatesAutoresizingMaskIntoConstraints = false
adAttribution.text = "Ad"
adAttribution.textColor = .white
adAttribution.textAlignment = .center
adAttribution.backgroundColor = UIColor(red: 1, green: 0.8, blue: 0.4, alpha: 1)
adAttribution.font = UIFont.systemFont(ofSize: 11, weight: UIFont.Weight.semibold)
return adAttribution
}()
override var nativeContentAd: GADNativeContentAd? {
didSet {
if let nativeContentAd = nativeContentAd, let callToActionView = callToActionView {
nativeContentAd.register(self,
clickableAssetViews: [GADNativeContentAdAssetID.callToActionAsset: callToActionView],
nonclickableAssetViews: [:])
}
}
}
init() {
super.init(frame: CGRect.zero)
translatesAutoresizingMaskIntoConstraints = false
backgroundColor = .white
isUserInteractionEnabled = true
callToActionView = tappableOverlay
headlineView = myHeadlineView
imageView = myImageView
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func didMoveToSuperview() {
super.didMoveToSuperview()
addSubview(myHeadlineView)
addSubview(myImageView)
addSubview(adAttribution)
addSubview(tappableOverlay)
}
// override func updateConstraints() {
// ....
// }
}
Just be sure to pin the tappableOverlay to its superview edges so that they're the same size...in updateConstraints().
Inside the method simply you can create and place Ad in view hierarchy.
GADNativeContentAdView *contentAdView = [[NSBundle mainBundle] loadNibNamed:#"NativeAdView" owner:nil options:nil].firstObject;
After assigning the properties, associate the content Ad view with the content ad object. This is required to make the ad clickable.
contentAdView.nativeContentAd = nativeContentAd;
Only AdMob whitelisted publishers can use the registerAdView API :)
All publishers can use xib to create an ad view.
Don't forget to link custom GADUnifiedNativeAdView outlets to your UILabels, UIButtons and ImageViews, so GADUnifiedNativeAdView will know what to interact with
In my case it was cause I created my views without xib.
In this case just set mediaView property to your GADNativeAdView
here the minimum working code
final class EndBannerController: UIViewController {
private let adId: String
private let adView = GADNativeAdView()
private let mediaView = GADMediaView()
private var adLoader: GADAdLoader?
init(adId: String) {
self.adId = adId
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) { return nil }
override func viewDidLoad() {
super.viewDidLoad()
adView.frame = view.bounds
view.addSubview(adView)
mediaView.frame = view.bounds
adView.mediaView = mediaView
adView.addSubview(mediaView)
let loader = GADAdLoader(
adUnitID: adId,
rootViewController: self,
adTypes: [.native],
options: nil
)
loader.delegate = self
self.adLoader = loader
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.loadBannerAd()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
adView.frame = view.bounds
mediaView.frame = view.bounds
}
private func loadBannerAd() {
let request = GADRequest()
request.scene = view.window?.windowScene
self.adLoader?.load(request)
}
}
I want to refresh tableView appearance after I press "Dark mode".But it looks like this:
Before press"Dark mode"
After press"Dark mode"
How can I refresh this tableView after I changed it's appearance
Mycode:
#IBAction func setDarkMode(sender: UISwitch) {
UIView.animateWithDuration(0.5, delay:0,options:UIViewAnimationOptions.BeginFromCurrentState, animations: { () -> Void in
self.setStyleMode()
}) { (finish: Bool) -> Void in
}
}
func setStyleMode() {
if isDarkMode {
view.backgroundColor = UIColor(red:0.1922, green:0.1922, blue:0.1922, alpha:1.0)
self.tableView.backgroundView?.backgroundColor = UIColor(red:0.1922, green:0.1922, blue:0.1922, alpha:1.0)
tableView.separatorColor = UIColor(red:0.3137, green:0.3137, blue:0.3137, alpha:1.0)
self.navigationController?.navigationBar.barTintColor = UIColor(red:0.1451, green:0.1451, blue:0.1451, alpha:1.0)
self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor(red:0.6549, green:0.6549, blue:0.6549, alpha:1.0)]
self.navigationController?.navigationBar.tintColor = UIColor(red:0.9412, green:0.3412, blue:0.302, alpha:1.0)
for sectionIndex in 0...tableView.numberOfSections - 1 {
for rowIndex in 0...tableView.numberOfRowsInSection(sectionIndex) - 1 {
let cellPath = NSIndexPath(forRow: rowIndex, inSection: sectionIndex)
let cell = tableView.cellForRowAtIndexPath(cellPath)
cell?.backgroundColor = UIColor(red:0.1451, green:0.1451, blue:0.1451, alpha:1.0)
}
}
for aLabel in labels {
aLabel.textColor = UIColor(red:0.6549, green:0.6549, blue:0.6549, alpha:1.0)
}
} else {
view.backgroundColor = UIColor.whiteColor()
tableView.backgroundColor = UIColor(red:0.9529, green:0.9529, blue:0.9529, alpha:1.0)
tableView.separatorColor = UIColor(red:0.7372, green:0.7371, blue:0.7372, alpha:1.0)
self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor()
self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.blackColor()]
self.navigationController?.navigationBar.tintColor = UIColor(red:0.9412, green:0.3412, blue:0.302, alpha:1.0)
for sectionIndex in 0...tableView.numberOfSections - 1 {
for rowIndex in 0...tableView.numberOfRowsInSection(sectionIndex) - 1 {
let cellPath = NSIndexPath(forRow: rowIndex, inSection: sectionIndex)
let cell = tableView.cellForRowAtIndexPath(cellPath)
cell?.backgroundColor = UIColor.whiteColor()
//do stuff with 'cell'
}
}
for aLabel in labels {
aLabel.textColor = UIColor.blackColor()
}
}
}
(This "settings" tableView is in a "tableviewController " and embed in a ContainerView)
Looks like you have not called reloadData()
Once your style changes are over call call execute the following code
tableView.reloadData()
Another thing is, styling your tableViewCellshould be done inside
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
Not inside setStyleMode() function. You can make the style changes based on some bool value.
Hope this will resolve your issue
You're setting the cell's background color, but not the cell's contentView's background color.
You should do:
let cell = tableView.cellForRowAtIndexPath(cellPath)
cell?.backgroundColor = ....
cell?.contentView.backgroundColor = ....
You might have to dig deeper if your cell has more wrapper views in the hierarchy.
A couple of observations, though:
It would be a better pattern to define a method within the UITableViewCell subclass to define a dark and light mode. In complex cell structures, you might not easily be able to access all the subviews you need. Besides, what about encapsulation?
I would also much prefer the reload way. Calling a UITableViewDatasource method manually seems like an anti-pattern.
There's a lot of duplication in your code. You could significantly reduce the dependency by, for instance, using ternary operators on isDarkMode
Need change background of "headerView" and "footerView" in "setStyleMode()"
let header = tableView.headerViewForSection(sectionIndex)
let footer = tableView.footerViewForSection(sectionIndex)
header?.contentView.backgroundColor = UIColor(red:0.1922, green:0.1922, blue:0.1922, alpha:1.0)
footer?.contentView.backgroundColor = UIColor(red:0.1922, green:0.1922, blue:0.1922, alpha:1.0)
I'd like to change the color of my cell accessoryType from blue to white.
The textColor is already set to white.
Does someone of you guys know how to do this?
My Code:
cell!.accessoryType = UITableViewCellAccessoryType.Checkmark
You can set your UITableViewCell tintColor property to the desired color:
[cell setTintColor:[UIColor whiteColor]];
Doesn't work for .disclosureIndicator ?
If someone is here looking for "How to change color for .disclosureIndicator indicator type".
The answer is you can't. BUT:
There is a way. Apply a custom image:
let chevronImageView = UIImageView(image: "disclosureIndicatorImage"))
accessoryView = chevronImageView
Additional supporting links:
The image can be downloaded from here.
How to change color of the image is here.
Swift:
cell.tintColor = UIColor.whiteColor()
Swift 3.0
cell.tintColor = UIColor.white
"How to change color for .disclosureIndicator indicator type". After much research, I noticed that the image of disclosureIndicator is not an Image but a backgroundImage. I found a solution like this:
import UIKit
class CustomCell: UITableViewCell {
fileprivate func commonInit() {
}
open override func layoutSubviews() {
super.layoutSubviews()
if let indicatorButton = allSubviews.compactMap({ $0 as? UIButton }).last {
let image = indicatorButton.backgroundImage(for: .normal)?.withRenderingMode(.alwaysTemplate)
indicatorButton.setBackgroundImage(image, for: .normal)
indicatorButton.tintColor = .red
}
}
}
extension UIView {
var allSubviews: [UIView] {
return subviews.flatMap { [$0] + $0.allSubviews }
}
}
Swift 3.1:
cell.backgroundColor = UIColor.yellow // the accessoryType background
cell.tintColor = UIColor.black // the accessoryType tint color.
Swift 5 I am Improving Tung Fam Answer
let chevronImageView = UIImageView(image: UIImage(named: "chevron-right"))
cell.accessoryView = chevronImageView
You can also change the cell's tint color from the storyboard (assuming you are using a xib file)
Im my case i need to change contentView color of my CustomCell.
Its can be easy making when u override methods :
override func setHighlighted(highlighted: Bool, animated: Bool) {}
and:
override func setSelected(selected: Bool, animated: Bool) {}
But when i add to my customCell :
cell?.accessoryType = .DisclosureIndicator
i had a problem when view under DisclosureIndicator is not change color. Its looks like:
So i look on subviews of CustomCell and find that DisclosureIndicator is a button. If change background color of this button u have this
So i try to change background color of superview of this button. And its work great.
Full code of myCustomCell setHighlighted func :
override func setHighlighted(highlighted: Bool, animated: Bool) {
if(highlighted){
viewContent.view.backgroundColor = Constants.Colors.selectedBackground
for item in self.subviews {
if ((item as? UIButton) != nil) {
item.superview?.backgroundColor = Constants.Colors.selectedBackground
}
}
} else {
viewContent.view.backgroundColor = Constants.Colors.normalCellBackground
for item in self.subviews {
if ((item as? UIButton) != nil) {
item.superview?.backgroundColor = Constants.Colors.normalCellBackground
}
}
}
}
The best way to do that, I think, is to set accessory to image the following way:
let image = UIImage(named: "some image.png")
cell.accessoryView = image
cell.contentView.backgroundColor = .grey
cell.backgroundColor = .grey