简体   繁体   中英

Swift: how to deal with tableView when tableView width is wider than screen size?

The scene I need to implement the attached picture. When I try to implement the bottom form, I meet some problems.

The bottom form has following requirements:

  1. top 2 lines should stick at the head, and not allow to scroll up/down. I use table section head to implement.

  2. all the other rows could scroll up/down and clickable. I use a table view to implement

  3. since the app support bigger text, when text is bigger, the screen size could not display all the tableView, so in this case, the whole tableview should support horizontally scroll.

  4. when tableview row data is different from the "currentBitting", which has a value of "33342431", the individual label should show background colour.

  5. each column should be aligned for the table

Following is the idea how I implement:

  1. To achieve all these requirements, I use tableView to implement. Each character in the array item use label to display.

  2. I use the max width and regular width to define the width of each column

  3. When text font size changes, I try to set the bottom tableView contentSize = current new content size in "viewWillLayoutSubViews()"

  4. I add a background colour for the section head, otherwise, when bottom tableview scroll up, it will overlap the section head and offscreen text background colour does not render. So I add section head background colour to avoid this problem.

Currently, the problem is the horizontal scroll does not work. Very strange.

To be honest, I tried quite a lot of ways:

  1. bottom form first uses a parent scrollView, then put a sub tableView. Problem: top header is hard to stick or vertically scroll not that smooth. I pasted my scrollViewDidScroll part. It works. But vertically scroll not that smooth. If anyone could help to improve it, I will be very appreciated.
    func scrollViewDidScroll(_ scrollView: UIScrollView) {

        let recognizer = scrollView.panGestureRecognizer

        let distance = recognizer.translation(in: scrollView)

        let deltaHeight:CGFloat = parentScrollView.contentSize.height - parentScrollView.frame.height

        let goingUp = distance.y < 0 //going up
        if distance.y != 0 {

            if goingUp {
                parentScrollView.contentOffset.y = 0
                switch recognizer.state {
                case .began,.changed:
                    if bottomTableview.contentOffset.y < deltaHeight {
                        bottomTableview.contentOffset.y -= distance.y
                        recognizer.setTranslation(.zero, in: scrollView)
                    }
                case .ended:
                    if bottomTableview.contentOffset.y > deltaHeight{
                        bottomTableview.contentOffset.y = deltaHeight
                        UIView.animate(withDuration: 0.1, animations: {
                            scrollView.layoutIfNeeded()
                        })
                    }
                default:
                    break 
                }  
            }
            else{
                switch recognizer.state {
                case .began,.changed:
                    if bottomTableview.contentOffset.y > 0 {
                        bottomTableview.contentOffset.y -= distance.y
                        recognizer.setTranslation(.zero, in: scrollView)
                    }
                case .ended:
                    if bottomTableview.contentOffset.y < 0 {
                        bottomTableview.contentOffset.y = 0
                        UIView.animate(withDuration: 0.1, animations: {
                            scrollView.layoutIfNeeded()
                        })
                    }
                default:
                    break
                } 
            }
        }
    }


  1. collection view to implementing. But I don't know how to select a whole line to get the data and how to stick the top header

Does anyone have some better idea to implement this case? Very appreciated for your help.

Data to use in the table view is:

let extensionCodeArray = ["Position", "Current Bitting", "11407", "10253", "10492", "14195", "11665", "10547", "12332", "12536", "10211", "11034", "10725", "11036", "12928"]
let extensionResultBitting = ["12345678", "33342431", "33133244", "33243134", "32343134", "33134243", "31343234", "33342134", "31344233", "34342133", "31334342", "33134342", "34343132", "34231343", "32431343"]

屏幕截图

For first solution you tried.

UITableView is a subclass of UIScrollView , which means UITableView also have scrollViewDidScroll(_ scrollView: UIScrollView) event.

To solve this, you could simply do the following. Set a tag to tableView or scrollView to identify it.
1. For example, to identify the scrollView, add the following line after where you initialized the scrollView.

scrollView.tag = 101  
  1. In func scrollViewDidScroll(_ scrollView: UIScrollView)
    func scrollViewDidScroll(_ scrollView: UIScrollView) 
     {
        if scrollView.tag == 101 { 
          // Triggered by scrollView
         } else { 
         // Triggered by tableView 
        }

     }

I solved the problem. The idea is below:

  1. define a collection view, set its numberOfItemsInSection = 1
  2. for the collectionView, set its
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize --> return CGSize(width: contentSize.width, height: collectionView.frame.size.height)

The cotentSize is calculated in advance for the final form

  1. Customerize the UICollectionViewCell , inside which implementing the tableView data source and delegate . All the datasource for the tableView get from a protocol defined in the UICollectionViewCell . Outerside collectionView is the delegate for the protocol

Done.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM