【发布时间】:2020-02-23 00:17:58
【问题描述】:
我正在尝试实现类似于this video 中可以看到的效果。
请注意,我说的是“垂直显示”效果,而不是“水平轮播”效果。
理想情况下,它应该与 UITableView 一起使用,但我知道这是不可能的。
【问题讨论】:
标签: ios uitableview user-interface
我正在尝试实现类似于this video 中可以看到的效果。
请注意,我说的是“垂直显示”效果,而不是“水平轮播”效果。
理想情况下,它应该与 UITableView 一起使用,但我知道这是不可能的。
【问题讨论】:
标签: ios uitableview user-interface
您可以通过创建具有 tableView 父级高度的页脚视图来实现此行为。
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var footer: UIView!
var tableView: UITableView!
let cellId = "CellID"
override func viewDidLoad() {
super.viewDidLoad()
let redView = UIView()
redView.backgroundColor = UIColor.red
redView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
redView.center = self.view.center
redView.autoresizingMask = [.flexibleLeftMargin, .flexibleTopMargin, .flexibleRightMargin, .flexibleBottomMargin]
self.view.addSubview(redView)
let footer = UIView()
footer.backgroundColor = UIColor.clear
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
footer.addGestureRecognizer(tapRecognizer)
self.footer = footer
let tableView = UITableView()
tableView.showsVerticalScrollIndicator = false
tableView.backgroundColor = .clear
tableView.dataSource = self
tableView.delegate = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellId)
tableView.frame = self.view.bounds
tableView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
self.view.addSubview(tableView)
self.tableView = tableView
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
cell.textLabel?.text = "\(indexPath.row)"
cell.backgroundColor = .green
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 200
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
return self.footer
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return self.view.bounds.height
}
@objc func handleTap(sender: UITapGestureRecognizer) {
self.tableView.frame.origin.y = self.view.bounds.height
self.tableView.contentOffset = .zero
UIView.animate(withDuration: 1) {
self.tableView.frame.origin.y = self.view.bounds.origin.y
}
}
}
【讨论】:
我最终做了以下事情:
TableViewController.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TableViewController : UITableViewController
@end
NS_ASSUME_NONNULL_END
TableViewController.m
#import "TableViewController.h"
#import "CustomCell.h"
#define ROW 7
#define ROW_HEIGHT 100
@interface TableViewController ()
@property (nonatomic, strong) CustomCell *customCell;
@end
@implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"IDENTIFIER1"];
self.customCell = [[CustomCell alloc] init];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == ROW) {
return self.customCell;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"IDENTIFIER1" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.text = [NSString stringWithFormat:@"%ld", indexPath.row];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == ROW) {
return self.tableView.frame.size.height;
}
return ROW_HEIGHT;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat offsetY = scrollView.contentOffset.y;
CGFloat top = ROW * ROW_HEIGHT;
if (offsetY >= top - scrollView.frame.size.height) {
self.customCell.mainView.frame = CGRectMake(0, offsetY - top, scrollView.frame.size.width, scrollView.frame.size.height);
}
}
@end
CustomCell.h
#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface CustomCell : UITableViewCell
@property (nonatomic, strong) WKWebView *mainView;
@end
NS_ASSUME_NONNULL_END
CustomCell.m
#import "CustomCell.h"
@implementation CustomCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.selectionStyle = UITableViewCellSelectionStyleNone;
self.contentView.backgroundColor = UIColor.greenColor; // XXX
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
self.mainView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
NSURL *url = [NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"test1.htm"]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.mainView loadRequest:request];
self.mainView.scrollView.bounces = NO;
self.mainView.scrollView.bouncesZoom = NO;
[self.contentView addSubview:self.mainView];
self.contentView.clipsToBounds = YES;
}
return self;
}
@end
test1.htm
<html>
<head><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"></head>
<style>
body {
margin: 24px;
background-color: #ffff00;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAAWdEVYdENyZWF0aW9uIFRpbWUAMTAvMjkvMTm1eHLxAAAAm0lEQVR4nO3QQRHAMAzAsGT8OWcw9KiFwOedmbu7nUd9OkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtAboAK0BOkBrgA7QGqADtOcH7MycjpB+hI8Fez5BjwUAAAAASUVORK5CYII=");
font-family: sans-serif;
font-size: 160px;
color: #ff0000;
}
</style>
<script>
function loop(timestamp) {
var element = document.getElementById("main");
element.innerText = timestamp;
window.requestAnimationFrame(loop);
}
window.requestAnimationFrame(loop);
</script>
<body>
<div id="main"></div>
</body>
</html>
【讨论】: