我试图使一行的内容(在UITableView中)有多个对齐方式:左,中,右。我在Stackoverflow上搜索了一个解决方案,发现了这个:Different text alignment to a row in table view。唯一的问题是该解决方案是基于ObjectiveC的,我无法转换为基于Swift的解决方案。
具体来说,我有一个表示活动用户列表的UITableView。将内容加载到表视图中工作正常,但为了便于阅读,内容(分为三种类型)需要在视觉上划分为三个不同的“部分”。我该怎么做呢?上面的解决方案在Swift中会是什么样子?提前谢谢。
代码(适用于Vive)
类声明
class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
viewDidLoad中()
self.activeIDs.delegate = self
self.activeIDs.dataSource = self
self.activeIDs.rowHeight = 25
self.activeIDs.separatorStyle = UITableViewCellSeparatorStyle.None
self.activeIDs.allowsMultipleSelection = true
的cellForRowAtIndexPath
func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell = activeIDs.dequeueReusableCellWithIdentifier("cellReuseId", forIndexPath: indexPath) as ActiveIDTableViewCell
cell.leftLabel.text = "I go left"
cell.middleLabel.text = "I go center"
cell.rightLabel.text = "I go right"
return cell
}
numberOfRowsInSection
func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return 4 //I randomly chose 4, just for example
}
ActiveIDTableViewCell.swift - 几乎已复制
import UIKit
class ActiveIDTableViewCell: UITableViewCell {
// alloc & init labels
let leftLabel = UILabel()
let middleLabel = UILabel()
let rightLabel = UILabel()
// MARK: Memory Management
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
// never forget to call super in overriden UIKit methods (almost never ;))
super.init(style: .Default, reuseIdentifier: reuseIdentifier)
// now let's assign these values we've set previously in storyboards
leftLabel.textAlignment = NSTextAlignment.Left
// you created a label, but you need to add this label as a subview of cells view.
contentView.addSubview(leftLabel)
middleLabel.textAlignment = NSTextAlignment.Center
contentView.addSubview(middleLabel)
rightLabel.textAlignment = NSTextAlignment.Right
contentView.addSubview(rightLabel)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented") //Xcode points to this line when error is thrown
}
// MARK: Layout
override func layoutSubviews() {
super.layoutSubviews()
// here happens all the magic which skips autolayouts. You can ofc set autolayouts from code :)
let frame = self.contentView.bounds
// frame was the size of the cell, but we want to set our labels at least 10px from sides of cell - so it looks nicely
let insetFrame = CGRectInset(frame, 10.0, 10.0)
// width of each label is width of cell / 3 (you want 3 labels next to each other) minus margins
let labelWidth = (CGRectGetWidth(insetFrame) - 20.0) / 3.0
// lets calculate the rects and assign frames to calculated values
let leftLabelRect = CGRectMake(CGRectGetMinX(insetFrame), CGRectGetMinY(insetFrame), labelWidth, CGRectGetHeight(insetFrame))
leftLabel.frame = leftLabelRect
let middleLabelRect = CGRectMake(CGRectGetMaxX(leftLabelRect), CGRectGetMinY(insetFrame), labelWidth, CGRectGetHeight(insetFrame))
middleLabel.frame = middleLabelRect
let rightLabelRect = CGRectMake(CGRectGetMaxX(middleLabelRect), CGRectGetMinY(insetFrame), labelWidth, CGRectGetHeight(insetFrame))
rightLabel.frame = rightLabelRect
}}
我已经仔细检查了故事板中是否正确设置了单元标识符和自定义类等内容。
答案 0 :(得分:0)
好的,小教程如何做,请根据编程最佳实践在您的问题下查看我的评论:
包含ViewController的第一个文件:
class MyTableViewController: UITableViewController {
// here ofc you'll have your array/dictionary of input data
let titles = ["iOS", "Android", "Windows Phone", "Firefox OS", "Blackberry OS", "Tizen", "Windows Mobile", "Symbian", "Palm OS"]
// this is to make sure how many rows your table should have
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titles.count
}
// here you dequeue tableViewCells, so they're reusable (so your table is fast & responding
// allocating new resources for new cell is very consuming
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: MyTableViewCell = tableView.dequeueReusableCellWithIdentifier("cellId", forIndexPath: indexPath) as! MyTableViewCell
// fill your data
cell.rightLabel.text = "I'm right cell"
cell.middleLabel.text = titles[indexPath.row]
cell.leftLabel.text = "I'm left cell"
return cell;
}
}
带有单元格类的第二个文件:
class MyTableViewCell: UITableViewCell {
@IBOutlet weak var leftLabel: UILabel!
@IBOutlet weak var middleLabel: UILabel!
@IBOutlet weak var rightLabel: UILabel!
}
现在如何告诉你如何处理IB:/。就个人而言,我更喜欢代码解决方案,但这是你的决定。
TableViewController
从对象带到您的情节提要板,Identity Inspector
将班级设为MyTableViewController
Identity Inspector
将类设置为MyTableViewCell
Update Frames
。一切都应该正确定位。Attributes Inspector
,在那里标记正确的对齐方式(左侧为标签,中间位置为中间标签,右侧为右侧标签)。MyTableViewCell
IBOutlets
。使用此解决方案,一切都应该可以正常工作。
答案 1 :(得分:0)
确定代码解决方案的另一个答案(因为它完全不同),而不是使用故事板:
更改以下AppDelegate代码的实现。
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// create window and set proper size of it
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window?.backgroundColor = UIColor.whiteColor()
self.window?.makeKeyAndVisible()
// assign your controller to be the 'entering' point
self.window?.rootViewController = UINavigationController(rootViewController: MyViewController(style:UITableViewStyle.Plain))
// start the app
return true
}
}
复制以下代码:
import UIKit
class MyViewController: UITableViewController {
// use let to keep ID, as at least in 2 places we need this string, it's easier to maintain it in one place and omit any typos
let cellReuseId = "cellReuseId"
let titles = ["iOS", "Android", "Windows Phone", "Firefox OS", "Blackberry OS", "Tizen", "Windows Mobile", "Symbian", "Palm OS"]
// MARK: Memory Management
override init(style: UITableViewStyle) {
super.init(style: style)
}
required init!(coder aDecoder: NSCoder!) {
fatalError("init(coder:) has not been implemented")
}
override init!(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
// MARK: View Lifecycle
override func viewDidLoad() {
// tell the table which class should be used to dequeue cells with given reuse id (previously you set it in storyboards)
tableView.registerClass(MyTableViewCell.self, forCellReuseIdentifier: cellReuseId)
}
// MARK: UITableViewDelegate && UITableViewDataSource
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titles.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellReuseId, forIndexPath: indexPath) as! MyTableViewCell
cell.rightLabel.text = "I'm right cell"
cell.middleLabel.text = titles[indexPath.row]
cell.leftLabel.text = "I'm left cell"
return cell
}
}
复制以下代码:
import UIKit
class MyTableViewCell: UITableViewCell {
// alloc & init labels
let leftLabel = UILabel()
let middleLabel = UILabel()
let rightLabel = UILabel()
// MARK: Memory Management
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
// never forget to call super in overriden UIKit methods (almost never ;))
super.init(style: .Default, reuseIdentifier: reuseIdentifier)
// now let's assign these values we've set previously in storyboards
leftLabel.textAlignment = NSTextAlignment.Left
// you created a label, but you need to add this label as a subview of cells view.
contentView.addSubview(leftLabel)
middleLabel.textAlignment = NSTextAlignment.Center
contentView.addSubview(middleLabel)
rightLabel.textAlignment = NSTextAlignment.Right
contentView.addSubview(rightLabel)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: Layout
override func layoutSubviews() {
super.layoutSubviews()
// here happens all the magic which skips autolayouts. You can ofc set autolayouts from code :)
let frame = self.contentView.bounds
// frame was the size of the cell, but we want to set our labels at least 10px from sides of cell - so it looks nicely
let insetFrame = CGRectInset(frame, 10.0, 10.0)
// width of each label is width of cell / 3 (you want 3 labels next to each other) minus margins
let labelWidth = (CGRectGetWidth(insetFrame) - 20.0) / 3.0
// lets calculate the rects and assign frames to calculated values
let leftLabelRect = CGRectMake(CGRectGetMinX(insetFrame), CGRectGetMinY(insetFrame), labelWidth, CGRectGetHeight(insetFrame))
leftLabel.frame = leftLabelRect
let middleLabelRect = CGRectMake(CGRectGetMaxX(leftLabelRect), CGRectGetMinY(insetFrame), labelWidth, CGRectGetHeight(insetFrame))
middleLabel.frame = middleLabelRect
let rightLabelRect = CGRectMake(CGRectGetMaxX(middleLabelRect), CGRectGetMinY(insetFrame), labelWidth, CGRectGetHeight(insetFrame))
rightLabel.frame = rightLabelRect
}
}
最后,我个人更喜欢代码的一个小解释: