我是一个Swift新手,我试图获得一些感觉应该很容易的东西但是我缺乏对Storyboard + Swift +术语的了解让我退缩了!
我想创建一个水平滚动组件,它实现了以下设计目标:
我创建了一个简单的示例滚动条,它具有以下结构:
我想这个组件可能会在ViewController的viewDidLoad()方法中使用,如下所示:
//**Pseudo code**
let data1 = ["a","b","c"]
let data2 = ["1","2","3"]
let scroller1:MyScroller = ScrollerFromData(data:data1)
scroller1.constraints = somePositioningConstraints
view.add(scroller1)
let scroller2:MyScroller = ScrollerFromDataWithCellType(data:data2,cellType:"MyCell2")
scroller2.constraints = someDifferentPositioningConstraints
view.add(scroller2)
如何将我的代码/结构转换为我可以按上述方式使用的内容的任何建议都会很棒。
HorizontalScrollerVC.swift
import UIKit
class HorizontalScrollerVC: UIViewController {
// set up some data
let dataArray = ["Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet"]
// create an outlet to communicate with the collectionView
@IBOutlet weak var myCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let cellNib = UINib(nibName: "MyCell", bundle: nil)
self.myCollectionView.registerNib(cellNib, forCellWithReuseIdentifier: "MyCell")
self.myCollectionView.backgroundColor = UIColor.init(colorLiteralRed: 0.9, green: 0.6, blue: 0.9, alpha: 1.0)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: CollectionView methods
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataArray.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCell", forIndexPath: indexPath) as! MyCell
self.configureCell(cell, forIndexPath: indexPath)
return cell
}
func configureCell(cell: MyCell, forIndexPath indexPath: NSIndexPath) {
let cellTitle = dataArray[indexPath.row]
cell.cellTitle.text = cellTitle
}
}
MyCell.swift
import UIKit
class MyCell: UICollectionViewCell {
@IBOutlet weak var cellTitle: UILabel!
override func awakeFromNib() {
self.backgroundColor = UIColor.init(colorLiteralRed: 0.95, green: 0.95, blue: 0.95, alpha: 1.0)
self.cellTitle.textColor = UIColor.darkGrayColor()
self.layer.cornerRadius = 5
}
}
MyCell.xib 非常简单,但有帮助,这里是xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MyCell" customModule="testola" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="210" height="140"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="4" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="h9Q-Ha-ZnF">
<rect key="frame" x="8" y="8" width="118" height="64"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="h9Q-Ha-ZnF" firstAttribute="trailing" secondItem="iN0-l3-epB" secondAttribute="trailingMargin" constant="-76" id="S2o-eE-CYh"/>
<constraint firstAttribute="bottomMargin" secondItem="h9Q-Ha-ZnF" secondAttribute="bottom" constant="60" id="U0s-fw-Rfv"/>
<constraint firstItem="h9Q-Ha-ZnF" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leadingMargin" id="rwe-wi-Vff"/>
<constraint firstItem="h9Q-Ha-ZnF" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="topMargin" id="sl1-pT-fj7"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="cellTitle" destination="h9Q-Ha-ZnF" id="8E8-HL-BCx"/>
</connections>
<point key="canvasLocation" x="195" y="139"/>
</view>
</objects>
</document>
这里是故事板 xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="49e-Tb-3d3">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
</dependencies>
<scenes>
<!--First-->
<scene sceneID="hNz-n2-bh7">
<objects>
<viewController id="9pv-A4-QxB" customClass="HorizontalScrollerVC" customModule="testola" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ia1-K6-d13"/>
<viewControllerLayoutGuide type="bottom" id="4ug-Mw-9AY"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="tsR-hK-woN">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="ZD4-S1-Vkm">
<rect key="frame" x="-4" y="40" width="383" height="150"/>
<constraints>
<constraint firstAttribute="height" constant="150" id="f2E-DB-ecy"/>
</constraints>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="10" minimumInteritemSpacing="10" id="AYp-cr-c33">
<size key="itemSize" width="210" height="140"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="10" minY="0.0" maxX="10" maxY="0.0"/>
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="zbW-CO-LP9">
<rect key="frame" x="10" y="-20" width="210" height="140"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="210" height="140"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</view>
<size key="customSize" width="210" height="140"/>
</collectionViewCell>
</cells>
<connections>
<outlet property="dataSource" destination="9pv-A4-QxB" id="p0g-qN-oUd"/>
<outlet property="delegate" destination="9pv-A4-QxB" id="U7n-os-ldT"/>
</connections>
</collectionView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="ZD4-S1-Vkm" firstAttribute="top" secondItem="Ia1-K6-d13" secondAttribute="bottom" constant="20" id="0Eh-uz-aT3"/>
<constraint firstAttribute="trailingMargin" secondItem="ZD4-S1-Vkm" secondAttribute="trailing" constant="-20" id="2wl-8R-h8o"/>
<constraint firstItem="ZD4-S1-Vkm" firstAttribute="leading" secondItem="tsR-hK-woN" secondAttribute="leadingMargin" constant="-20" id="XxF-oY-0Bo"/>
</constraints>
</view>
<tabBarItem key="tabBarItem" title="First" image="first" id="acW-dT-cKf"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<connections>
<outlet property="myCollectionView" destination="ZD4-S1-Vkm" id="xWz-Uu-tsB"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="W5J-7L-Pyd" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="749.5" y="-320.5"/>
</scene>
<!--Second-->
<scene sceneID="wg7-f3-ORb">
<objects>
<viewController id="8rJ-Kc-sve" customClass="SecondViewController" customModule="testola" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="L7p-HK-0SC"/>
<viewControllerLayoutGuide type="bottom" id="Djb-ko-YwX"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="QS5-Rx-YEW">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" text="Second View" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="zEq-FU-wV5">
<rect key="frame" x="83" y="313" width="210" height="42"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" name="Helvetica" family="Helvetica" pointSize="36"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Loaded by SecondViewController" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NDk-cv-Gan">
<rect key="frame" x="81" y="363" width="215" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="NDk-cv-Gan" firstAttribute="top" secondItem="zEq-FU-wV5" secondAttribute="bottom" constant="8" symbolic="YES" id="Day-4N-Vmt"/>
<constraint firstItem="NDk-cv-Gan" firstAttribute="centerX" secondItem="zEq-FU-wV5" secondAttribute="centerX" id="JgO-Fn-dHn"/>
<constraint firstAttribute="centerX" secondItem="zEq-FU-wV5" secondAttribute="centerX" id="qqM-NS-xev"/>
<constraint firstAttribute="centerY" secondItem="zEq-FU-wV5" secondAttribute="centerY" id="qzY-Ky-pLD"/>
</constraints>
</view>
<tabBarItem key="tabBarItem" title="Second" image="second" id="cPa-gy-q4n"/>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="4Nw-L8-lE0" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="750" y="360"/>
</scene>
<!--Tab Bar Controller-->
<scene sceneID="yl2-sM-qoP">
<objects>
<tabBarController id="49e-Tb-3d3" sceneMemberID="viewController">
<nil key="simulatedBottomBarMetrics"/>
<simulatedScreenMetrics key="simulatedDestinationMetrics" type="retina47"/>
<tabBar key="tabBar" contentMode="scaleToFill" id="W28-zg-YXA">
<rect key="frame" x="0.0" y="975" width="768" height="49"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</tabBar>
<connections>
<segue destination="9pv-A4-QxB" kind="relationship" relationship="viewControllers" id="u7Y-xg-7CH"/>
<segue destination="8rJ-Kc-sve" kind="relationship" relationship="viewControllers" id="lzU-1b-eKA"/>
</connections>
</tabBarController>
<placeholder placeholderIdentifier="IBFirstResponder" id="HuB-VB-40B" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="0.0" y="0.0"/>
</scene>
</scenes>
<resources>
<image name="first" width="30" height="30"/>
<image name="second" width="30" height="30"/>
</resources>
</document>
答案 0 :(得分:2)
之前我做过一些自定义控件。我过去所做的是从UIView创建一个子类。然后使用IBDesignable我可以开始为我的控件编写代码,并在编码时显示在Storyboard中。完成后,只需将UIView拖放到Storyboard,然后将类更改为您刚刚创建的自定义类。由于它将是一个IBDesignable注释类,您将能够在屏幕上看到它作为您的控件,而不仅仅是一个简单的UIView。将自定义控件放在Storyboard中后,还可以使用自动布局来定义其他内容,例如控件的宽度等。
您提到将数据传递给视图控制器。我在我的项目中使用了类似的东西。
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let feed = segue.destinationViewController as? FeedTableViewController
where segue.identifier == "EmbedFeed" {
feed.yourVariable = [1,2,3]
}
}
答案 1 :(得分:0)
我有一个解决方案,所以我认为我发布简单的代码,以防任何像我这样的新手发现这篇文章(它是非常基本的东西)。
逻辑是:
new
- &gt; Cocoa Touch Class
- &gt; Subclass of
UIViewController AND check the
同时创建XIB文件框let myCustomWidget = CustomViewController(nibName: "CustomViewController", bundle: nil)
self.addChildViewController(myCustomWidget)
self.masterView.addSubview(myScroller.view)
一个简单的例子
我们最终得到了什么(A&#39;主要&#39;视图,其中添加了几个自定义类实例作为子视图):
FirstViewController.swift (&#39; master&#39; ViewController)
import UIKit
class FirstViewController: UIViewController {
// create this outlet by ctrl+dragging in Storyboard's Assistant view
@IBOutlet var firstView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// instantiate as many custom VCs as you want (I have a .xib called "ScrollerViewController.xib")
let myScroller = ScrollerViewController(nibName: "ScrollerViewController", bundle: nil)
let myScroller2 = ScrollerViewController(nibName: "ScrollerViewController", bundle: nil)
// add the custom VC to the current VC
self.addChildViewController(myScroller)
// add the custom VC's view to the current VC's view (set via IBOutlet above)
self.firstView.addSubview(myScroller.view)
// ...do it again for the 2nd custom VC
self.addChildViewController(myScroller2)
self.firstView.addSubview(myScroller2.view)
// move 2 so we can see it (use constraints in production)
myScroller2.view.frame = CGRectOffset(myScroller2.view.frame, 0, 150);
// Set up some data
let dummyData = ["Wotcha!","Hello there"]
// Pass the data to each instance of the custom VC
// Note: this has to be done AFTER we've added it to the 'master' view
myScroller.myTitle.text = dummyData[0]
myScroller2.myTitle.text = dummyData[1]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
<强> ScrollerViewController.swift 强>
import UIKit
class ScrollerViewController: UIViewController {
// create an outlet to show that the passed in data works
@IBOutlet var myTitle: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}