I have UIButton inside cell of UITableView, When i touch the button it is actually working but the animation of highlighted is not being seen, I have tried setting delaysContentTouches = false on viewDidLoad and also on IB
I even tried to find UIScrollVIew of table view so that i can set that properties to false, like...
for cls in cell.subviews
{
println("name of class is ::\(NSStringFromClass(cls.classForCoder))")
if NSStringFromClass(cls.classForCoder) == "UITableViewCellScrollView"
{
cls.scrollView.delaysContentTouches = false
break
}
}
Thanks in advance!
UITableView subclass
override public var delaysContentTouches: Bool {
didSet {
if let subviews = self.subviews as? [UIView] {
for view in subviews {
if let scroll = view as? UIScrollView {
scroll.delaysContentTouches = delaysContentTouches
}
break
}
}
}
}
Related
I'm trying to set tableHeaderView height by the UILabel that I placed inside. But for some reason I have problems with it, the height is smaller than the label's content and for sometimes the label won't show the full text.
This is how it looks:
This is how it should look:
This is my code:
extension UITableView {
public func relayoutTableHeaderView() {
if let tableHeaderView = tableHeaderView {
let labels = tableHeaderView.findViewsOfClass(viewClass: UILabel.self)
for label in labels {
label.preferredMaxLayoutWidth = label.frame.width
}
tableHeaderView.setNeedsLayout()
tableHeaderView.layoutIfNeeded()
tableHeaderView.frame.size.height = tableHeaderView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
self.tableHeaderView = tableHeaderView
print(tableHeaderView.frame)
}
}
}
extension UIView {
public func findViewsOfClass<T:UIView>(viewClass: T.Type) -> [T] {
var views: [T] = []
for subview in subviews {
if subview is T {
views.append(subview as! T)
}
views.append(contentsOf: subview.findViewsOfClass(viewClass: T.self))
}
return views
}
}
The resource of this piece of code here.
You are not using Number of lines to zero
extension UITableView {
public func relayoutTableHeaderView() {
if let tableHeaderView = tableHeaderView {
let labels = tableHeaderView.findViewsOfClass(viewClass: UILabel.self)
for label in labels {
label.preferredMaxLayoutWidth = label.frame.width
label.numberOfLines = 0
}
tableHeaderView.setNeedsLayout()
tableHeaderView.layoutIfNeeded()
tableHeaderView.frame.size.height = tableHeaderView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
self.tableHeaderView = tableHeaderView
print(tableHeaderView.frame)
}
}
}
I'm trying to get the content size of UITableView in runtime, where I working on library that will do some moves when pop over the views and to do this I wrote this code inside the library to figure out that inside the presented view will be UITableView:
if view.isKind(of: UIView.self) {
for subView in view.subviews {
for sv in subView.subviews {
if sv.isKind(of: UITableView.self) {
print(sv.frame.size.height)
Here I got the table view, but I couldn't get the contentSize property
print("table view found")
}
}
}
}
Any tips how to get its content size ?!
Use a cast instead of a test so that the compiler knows the object's properties:
if view.isKind(of: UIView.self) {
for subView in view.subviews {
for sv in subView.subviews {
if let tableView = sv as? UITableView {
print(tableView.contentSize.height)
}
}
}
}
Does anybody know is there any way to call status bar tapping programmatically when view appeared? My view is not on the top when appearing.
Thank you!
I'm going to assume that what you want to do is scroll your view to the top, which is what tapping the status bar does. If that's the case then here is a nice little view controller extension to achieve that.
extension UIViewController {
func scrollToTop() {
func scrollToTop(view: UIView?) {
guard let view = view else { return }
switch view {
case let scrollView as UIScrollView:
if scrollView.scrollsToTop == true {
scrollView.setContentOffset(CGPoint(x: 0.0, y: -scrollView.contentInset.top), animated: true)
return
}
default:
break
}
for subView in view.subviews {
scrollToTop(view: subView)
}
}
scrollToTop(view: view)
}
var isScrolledToTop: Bool {
for subView in view.subviews {
if let scrollView = subView as? UIScrollView {
return (scrollView.contentOffset.y == 0)
}
}
return true
}
}
Then in the viewDidAppear of your view controller, you can call
myViewController.scrollToTop()
I have many views and for each views, many subviews.
I tried to specify for each subviews
scrollsToTop = false
but my TableView doesn't scroll to top when I press the status bar.
I suppose I missed some views...
I know there is a similar post but it doesn't answer (UITableView scroll to top when tapping status bar at top of the screen)
So I decided to implement this function:
override func viewDidLoad() {
super.viewDidLoad()
checkForScrollViewInView(self.view)
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.scrollsToTop = true
}
func checkForScrollViewInView(view:UIView) {
for subview in view.subviews as [UIView] {
if subview.isKindOfClass(UITextView) {
(subview as! UITextView).scrollsToTop = false
}
if subview.isKindOfClass(UIScrollView) {
(subview as! UIScrollView).scrollsToTop = false
}
if subview.isKindOfClass(UITableView) {
(subview as! UITableView).scrollsToTop = false
}
if (subview.subviews.count > 0) {
self.checkForScrollViewInView(subview)
}
}
}
But it doesn't work too. I don't know what I miss.
You may stuggle with 2 problems:
You have more than one instance of UIScrollView. You should disable scrollsToTop (eg. self.collectionView?.scrollsToTop = false in viewDidLoad) for the parent UIScrollView or objects that inherit from it (like UITableView or UICollectionView).
From Apple scrollViewShouldScrollToTop(_:)
If the delegate doesn’t implement this method, true is assumed. For the scroll-to-top gesture (a tap on the status bar) to be effective, the scrollsToTop property of the UIScrollView must be set to YES.
If your hierarchy is highly customized method scrollViewShouldScrollToTop won't be called. You should check why does happen. Otherwise you will have to some dirty work: add some gestures and handle them.
Interesting links:
Scroll to top of UITableView by tapping status bar
Why doesn't UIScrollView/UITableview respond to taps on the status bar, and scroll to the top?
https://developer.apple.com/library/prerelease/ios//documentation/UIKit/Reference/UIScrollViewDelegate_Protocol/index.html#//apple_ref/occ/intfm/UIScrollViewDelegate/scrollViewShouldScrollToTop:
Ok I found why my tableview wouldn't scroll!
I called my checkForScrollViewInView() function only in the viewDidLoad of my table view's view controller. In order to disable scrollToTop for every child views.
But I forgot that I had another "active" view controller... In my app I have a left menu which opens to swipe. Calling checkForScrollViewInView() in the left menu's view controller solves my issue.
func checkForScrollViewInView(view:UIView) {
for subview in view.subviews as [UIView] {
if subview.isKindOfClass(UITextView) {
(subview as! UITextView).scrollsToTop = false
}
if subview.isKindOfClass(UIScrollView) {
(subview as! UIScrollView).scrollsToTop = false
}
if subview.isKindOfClass(UITableView) {
(subview as! UITableView).scrollsToTop = false
}
if (subview.subviews.count > 0) {
self.checkForScrollViewInView(subview)
}
}
}
I have created a UIScrollView in a ContainerView and a UITextView as a subview of UIScrollView. I initialize the textView with scrollEnabled set to true. Now based on the contentOffset.y of the scrollView, I want to keep toggling scrollEnabled on the textView. But for some reason, once I set scrollEnabled to false, I can't seem to enable scroll again...
override func viewDidload() {
self.scrollView = UIScrollView(frame: CGRectMake(...))
self.scrollView.delegate = self
self.view.addSubview(self.scrollView)
self.textView = UITextView(frame: CGRectMake(...))
self.textView.scrollEnabled = true
self.textView.userInteractionEnabled = true
self.scrollView.addSubview(self.textView)
}
func scrollViewDidScroll(scrollView: UIScrollView) {
if self.scrollView.contentOffset.y >= 180 {
self.textView.scrollEnabled = true // This does not work!
} else {
self.textView.scrollEnabled = false // This works!
}
}
I was faced with the same problem, and eventually dealt with it by subclassing UITextView as shown below:
class TextView: UITextView {
var displayScrolling: Bool = true {
didSet {
self.showsVerticalScrollIndicator = displayScrolling
}
}
override var contentOffset: CGPoint {
set {
if displayScrolling {
super.contentOffset = newValue
}
}
get {
return super.contentOffset
}
}
}
At init (or in interface builder), set your instance of TextView to allow scrolling. In order to not scroll, set the 'displayScrolling' var to false. When you want to scroll, set 'displayScrolling' to true.
It will be scroll enabled if the text is longer.
I wish you luck!