Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
iOS ʵÏÖÂö³åÀ×´ïÒÔ¼°¶¯Ì¬Ôö¼õÔªËØ By Swift
 
×÷Õß BanningsµÄ²©¿Í£¬»ðÁú¹ûÈí¼þ    ·¢²¼ÓÚ 2014-08-25
  3794  次浏览      30
 

¿ªÊ¼Ö®Ç°

Swift¾­¹ýXcode6 Beta4Ò»°æ¸üк󣬻ù±¾ÉÏÒѾ­¿ÉÒÔ×÷ΪÉú²ú¹¤¾ßÁË£¬ËäÈ»ÓÐһЩµØ·½ºÍObjC±ÈÆðÀ´Òª¡°Âäºó¡±Ò»Ð©£¬µ«Ò²ÎÞÉË´óÑÅ¡£ÕâÀï¾ÍÓÃXcode6 Beta4+iOS SDK 8.0¿ª·¢£¬Èç¹ûÓÃObjCµÄ»°£¬Ö»Ðè°ÑijЩÓï·¨ºÍµ÷Ó÷½Ê½Ì滻һϾͿÉÒÔÁË¡£
×îÖÕЧ¹û£º

´´½¨»ù±¾¶¯»­

´´½¨Ò»¸öSingle View Application¹¤³Ì£¬ÔÙ´´½¨Ò»¸öSwiftÎļþ£¬ÎÒ´´½¨µÄ½Ð¡°PulsingRadarView¡±£¬Ä¿Ç°½á¹¹Îª£º

ÔÚViewControllerÀïÃæ³ÖÓÐÒ»¸öOptionalµÄPulsingRadarViewµÄÊôÐÔ£¬±íʾ¿ÉÒÔΪnil£¬È»ºóÔÚviewDidLoadÀï×öÒ»¸ö¼òµ¥µÄ³õʼ»¯¹¤×÷£º

class ViewController: UIViewController {  
var radarView: PulsingRadarView?
override func viewDidLoad() {
super.viewDidLoad()

let radarSize = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.width)
radarView = PulsingRadarView(frame: CGRectMake(0,(self.view.bounds.size.height-radarSize.height)/2,
radarSize.width,radarSize.height))
self.view.addSubview(radarView)
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

À×´ïÊÇÔ²Ðεģ¬ËùÒÔ¿í¸ß¶¼ÊÇself.view.bounds.size.width¡£

PulsingRadarViewÀïÃæÏÖÔÚÓ¦¸ÃÊǿյģ¬ÎÒÃÇÊ×Ïȵ¼ÈëQuartzCore£¬ÒòΪºóÃæ¶¯»­²¿·Ö»áÓõ½CALayer£¬È»ºóÖØÐ´drawRect·½·¨£º

override func drawRect(rect: CGRect) {  
UIColor.whiteColor().setFill()
UIRectFill(rect)

let pulsingCount = 6
let animationDuration: Double = 4

var animationLayer = CALayer()
for var i = 0; i < pulsingCount; i++ {
var pulsingLayer = CALayer()
pulsingLayer.frame = CGRectMake(0, 0, rect.size.width, rect.size.height)
pulsingLayer.borderColor = UIColor.grayColor().CGColor
pulsingLayer.borderWidth = 1
pulsingLayer.cornerRadius = rect.size.height / 2

var defaultCurve = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)

var animationGroup = CAAnimationGroup()
animationGroup.fillMode = kCAFillModeBackwards
animationGroup.beginTime = CACurrentMediaTime() + Double(i) * animationDuration / Double(pulsingCount)
animationGroup.duration = animationDuration
animationGroup.repeatCount = HUGE
animationGroup.timingFunction = defaultCurve

var scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
scaleAnimation.autoreverses = false
scaleAnimation.fromValue = Double(0)
scaleAnimation.toValue = Double(1.5)

var opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
opacityAnimation.values = [Double(1),Double(0.7),Double(0)]
opacityAnimation.keyTimes = [Double(0),Double(0.5),Double(1)]

animationGroup.animations = [scaleAnimation,opacityAnimation]

pulsingLayer.addAnimation(animationGroup, forKey: "pulsing")
animationLayer.addSublayer(pulsingLayer)
}
self.layer.addSublayer(animationLayer)
}

ÏÈÉèÖû­²¼µÄ±³Ó°É«Îª°×É«£¬pulsingCount±íʾ²¨ÐεÄÌõÊý£¬animationDuration±íʾ¶¯»­µÄʱ³¤£¬È»ºóÎÒ´´½¨ÁËÒ»¸öanimationLayerÀ´´æ·ÅËùÓе͝»­Layer------pulsingLayer£¬ÕâÑùlayerµÄ½á¹¹¿´ÆðÀ´¾ÍÏñ£º

ÿ¸öpulsingLayer´ú±íÒ»¸öÔ²ÐΣ¬Ñ­»·ÀïÃæÏȶÔpulsingLayer½øÐÐһЩ³õʼ»¯¹¤×÷£ºÉèÖÃframe¡¢±ß¿òÑÕÉ«¡¢±ß¿ò´óСÒÔ¼°radius£¨°ë¾¶£©£¬radius×ÔÈ»¾ÍÊÇ×ÔÉíµÄ¿í»ò¸ßµÄÒ»°ë¡£

CAMediaTimingFunctionÉÔºóÔÙ˵¡£

½ÓÏÂÀ´´´½¨Ò»¸öAnimationGroup£¬ÒòΪÎÒÃÇÐèÒªÓõ½µÄ¶¯»­½«ÓÐÁ½¸ö£ºscale£¨Ëõ·Å£©¡¢opacity£¨Í¸Ã÷£©£¬¶øÇÒÐèÒª¿ØÖƶ¯»­¿ªÊ¼µÄʱ¼ä¡£

ÎÒÃǽèÓÃControlling Animation TimingÕâÆªÎÄÕÂÖеļ¸ÕÅͼÀ´ËµÃ÷fillMode¡¢beginTimeÕâÁ½¸öÊôÐÔ£º

ÒÔÏÂÿ¸ö·½¸ñ´ú±í1ÃëÖÓ£¬ÏÂÃæÕâÕÅͼҲ¾Í´ú±í4ÃëÖÓ£¬¶¯»­Ê±¼äΪ1.5Ã룬»ÆÉ«Îª¶¯»­¿ªÊ¼£¬À¶É«Îª¶¯»­½áÊø£¬»ÆÉ«µ½À¶É«Ò²¾ÍÊǶ¯»­µÄ¹ý³Ì¡£´ÓͼÖпÉÒÔ¿´µ½£¬À¶É«²¿·Ö½áÊøºó¾ÍÊǰ×É«ÁË£¬Ò²¾Í´ú±íÕû¸ö¶¯»­½áÊø²¢ÇÒ´ÓlayerÉÏÒÆ³ý¡£

ÏÂÃæÕâÕÅͼ¿ªÊ¼¶¯»­Ê±¼äÆ«ÒÆÁË1Ã룬ÆäÓ಻±ä¡£

ĬÈÏÇé¿öÏ£¬ËùÓеÄLayerÎÞÂÛ´´½¨µÄÏȺó˳ÐòÓкβ»Í¬£¬ËüÃǵÄʱ¼äÏß¶¼ÊÇÒ»Öµģ¬beginTimeΪ0£¬±íʾ¼ÓÈëLayerÖ®ºó¾ÍÁ¢¼´¿ªÊ¼¶¯»­£¨»òÕß˵ÔÚµ±Ç°Ê±¼ä²¥·Å¶¯»­£©£¬¶øÈç¹ûÒªÆ«ÒÆ1Ã루ÈçÉÏͼ£©£¬ÔòÒªCACurrentMediaTime()+1£¬»ñÈ¡µ±Ç°ÏµÍ³µÄ¾ø¶Ôʱ¼ä£¨ÃëÊý£©²¢+1¡£ÎÒÃÇҪʵÏÖÂö³åЧ¹û£¬¾ÍҪʹÿһ¸öanimationGroupµÄ¶¯»­ÒÔ²»Í¬µÄbeginTimeÀ´½øÐУ¬ËùÒÔÒªÉèÖÃbeginTime = CACurrentMediaTime() + Double(i) * animationDuration / Double(pulsingCount)£¬Swift²»Ö§³ÖÒþʽÀàÐÍת»»£¬ÓÃDouble()ÏÔʽµÄǿתһÏ¡£

µ«ÊÇͨ¹ýÉÏͼ¿ÉÒÔ¿´µ½£¬Æ«Òƺ󶯻­¿ªÊ¼Ç°ÓÐÒ»¸ö¿Õµµ£¬ÕâÊÇÓÉfillMode¾ö¶¨µÄ:

1.kCAFillModeRemoved ĬÈÏÖµ,ÔÚ¶¯»­¿ªÊ¼Ç°ºÍ¶¯»­½áÊøºó,¶¯»­¶Ôlayer¶¼Ã»ÓÐÓ°Ïì,layerÔ­±¾ÊÇʲôÑù¾ÍÊÇʲôÑù

2.kCAFillModeForwards µ±¶¯»­½áÊøºó,layer»áÒ»Ö±±£³Ö×Ŷ¯»­×îºóµÄ״̬

3.kCAFillModeBackwards ºÍkCAFillModeForwardsÏà¶Ô,¾ßÌå²Î¿¼ÉÏÃæµÄ

4.kCAFillModeBoth kCAFillModeForwardsºÍkCAFillModeBackwardsÔÚÒ»ÆðµÄЧ¹û

ÔÚÎÒÃÇÏÖÔÚµÄÕâÖÖÇé¿öÏ£¬pulsingLayerÊÇÉèÖùýframeºÍborderµÄ£¬ËùÒÔÔÚ¶¯»­µÄ¿ÕµµÆÚ£¬pulsingLayer»áÖ±½ÓÏÔʾ³öÒ»¸ö´ø±ß¿òµÄÔ²ÐΣ¨¶¯»­»¹Ã»ÓпªÊ¼£©£¬µ±È»£¬ÔÚ¶¯»­²¥·Å¹ýÒ»´ÎÖ®ºó£¬Õâ¸ö±ß¿ò¾Í²»»áÏÔʾÁË£¬ÒòΪ½øÈëÁËÕý³£µÄ¶¯»­²¥·ÅÑ­»·£¬²»»á³öÏÖ¿ÕµµÆÚ¡£ÎÒÃÇÖ»ÐèÒª±ÜÃâÔÚ¶¯»­²¥·Åǰ²»³öÏÖ¿ÕµµÆÚ¾ÍÐÐÁË£¬¼´ÉèÖÃfillMode = kCAFillModeBackwards£¨Ìáǰ½øÈ붯»­×´Ì¬£©¡£

repeatCount = HUGE¾ÍÊÇ×ÖÃæÒâ˼£¬±íʾ¶¯»­ÎÞÏÞÑ­»·£¨HUGE¿ÉÒÔÈÏΪÊÇÎÞÏÞ£¬Èç¹ûÊÇObjC£¬ÓÃHUGE_VAL£©¡£

CAMediaTimingFunctionÓÉϵͳԤÖÃÁ˼¸¸öÖµ£º

1.kCAMediaTimingFunctionLinear ÏßÐÔ,¼´ÔÈËÙ

2.kCAMediaTimingFunctionEaseIn ÏÈÂýºó¿ì

3.kCAMediaTimingFunctionEaseOut ÏÈ¿ìºóÂý

4.kCAMediaTimingFunctionEaseInEaseOut ÏÈÂýºó¿ìÔÙÂý

5.kCAMediaTimingFunctionDefault ʵ¼ÊЧ¹ûÊÇÔÚ¶¯»­¿ªÊ¼Ê±ºÍ¶¯»­²¥·Åʱ±È½Ï¿ì,½«½áÊøÊ±»á±äÂý

CAMediaTimingFunctionÖ§³Ö±»¶¨ÖÆ¡£ÎÒÃǰÑtimingFunctionÉèÖÃΪkCAMediaTimingFunctionDefault£¬¿ÉÒÔʹ¶¯»­²¥·ÅµÄ¸ü¼Ó¶¯¸Ð¡£

½ÓÏÂÀ´µÄScale¶¯»­¾ÍºÜ¼òµ¥ÁË£¬´Ó0£¨0±¶£©µ½1.5£¨·Å´ó1.5±¶£©±ä»»¼´¿É¡£

Opacity͸Ã÷¶¯»­Ö»ÓÃÉèÖÃvaluesºÍÓëÆä¶ÔÓ¦µÄkeyTimes¾ÍÐÐÁË£¬ÐèҪעÒâµÄÊÇkeyTimes±íʾµÄÊÇʱ¼ä±ÈÀý£¬È¡Öµ0µ½1Ö®¼ä£¬ÈçvaluesµÄµÚÒ»¸öÔªËØÎª1£¬keyTimesµÚÒ»¸öÔªËØÎª0£¬±íʾ¶¯»­¿ªÊ¼Ê±£¬opacityΪ1£»valuesµÄµÚ¶þ¸öÔªËØÎª0.7£¬keyTimesµÚ¶þ¸öÔªËØÎª0.5£¬±íʾ¶¯»­²¥·Åµ½Ò»°ëµÄʱºò£¬opacityΪ0.7£»ÒÀ´ÎÀàÍÆ£¬¿É×ÔÓɶ¨ÖÆ¡£

È»ºó½«µ¥¶ÀµÄscale¶¯»­Óëopacity¶¯»­·â×°µ½animationGroupÀÔڰѰüº¬ÁËÁ½¸ö¶¯»­µÄanimationGroup¸øpulsingLayer£¬animationLayerÌí¼ÓpulsingLayer£¬×îºóÌí¼ÓÕâ¸ö°üº¬ÁËËùÓж¯»­LayerµÄanimationLayer¼´¿É¡£

¶¯Ì¬Ôö¼õÔªËØ

¶¯»­²¿·ÖÒѾ­Íê³ÉÁË£¬½ÓÏÂÀ´ÎÒÃǸøPulsingRadarViewÔö¼Ó½Ó¿Ú£¬Ê¹ÆäÖ§³ÖÔö¼õÔªËØ¡£

Ê×ÏȸøPulsingRadarViewÌí¼ÓÁ½¸öÊôÐÔ£º

class PulsingRadarView: UIView {  

let itemSize = CGSizeMake(44, 44)
var items = NSMutableArray()

µÚÒ»¸öÊÇÿ¸öitemµÄ³ß´ç£¬µÚ¶þ¸öÓÃÀ´´æ´¢ËùÓеÄitem¡£

Ìí¼ÓaddOrReplaceItem¹«¹²½Ó¿Ú£º

public func addOrReplaceItem() {  
let maxCount = 10

var radarButton = UIButton(frame: CGRectMake(0, 0, itemSize.width, itemSize.height))
radarButton.setImage(UIImage(named: "UK"), forState: UIControlState.Normal)

var center = generateCenterPointInRadar()
radarButton.center = CGPointMake(center.x, center.y)

self.addSubview(radarButton)
items.addObject(radarButton)

if items.count > maxCount {
var view = items.objectAtIndex(0) as UIView
view.removeFromSuperview()
items.removeObject(view)
}
}

maxCountÊÇÔ²ÄÚÏÔʾitemµÄ×î´óÖµ£¬ÕâÀï¼òµ¥µÄдËÀ£¬Äã¿ÉÒÔ°ÑËü¿ª·Å³öÈ¥³ÉΪһ¸ö¹«¹²µÄÊôÐÔ¡£ÕâÀïµÄÿ¸öitem¶¼ÊÇUIButton£¬³õʼ»¯ºóÉèÖÃÒ»ÕÅͼƬ¼´¿É£¬generateCenterPointInRadar·½·¨·µ»ØÒ»¸öÔ²ÄÚµÄÖÐÐÄ×ø±ê£¬Õâ¸ö×ø±êÖ»»áÔÚÔ²µÄÖ±¾¶ÒÔÄÚÉú³É£¬ÉÔºó·Å³ö¡£×îºóÅжÏÒ»ÏÂÓÐûÓг¬³ömaxCount£¬Èç¹û³¬³öÁË£¬¾Í°Ñ×îÏÈÌí¼ÓµÄitemÒÆ³ýµô¡£

ÔڷųögenerateCenterPointInRadarÕâ¸ö·½·¨Ö®Ç°£¬ÎÒÃÇÊ×ÏÈÒªÁ˽⣬Äĸö·¶Î§ÊÇÎÒÃǵÄ×ø±êÉú³É·¶Î§£º

´ó¼Ò¶¼ÖªµÀ£¬ViewµÄ»ù±¾ÐÎ×´ÊǾØÐΣ¨ºìÉ«ÇøÓò£©£¬drawRectÊÇÒÔRectΪ»ù´¡µÄ£¬µ«ÊÇÎÒÃÇÕâ¸öÀ×´ïÊÇÔ²ÐΣ¬Ò²¾ÍÊÇÀ¶É«ÇøÓò²ÅÊÇÎÒÃǵÄÄ¿±ê·¶Î§£¬ËùÒÔÉú³ÉµÄ×ø±êÒªÎ§ÈÆÖÐÐĵÄÂ̵㣨ԲÐÄ£©£¬ÈÃÎÒÃÇÖØÐ·­¿ªÊýѧ¿Î±¾£¬¿´¿´¸ßÖÐÊýѧ¶ÔÈý½Çº¯ÊýµÄ¶¨Ò壺

ÔÚÒ»¸öÆ½ÃæÖ±½Ç×ø±êϵÖУ¬ÒÔÔ­µãΪԲÐÄ£¬1 Ϊ°ë¾¶»­Ò»¸öÔ²£¬Õâ¸öÔ²½» x ÖáÓÚ A µã¡£ÒÔ O ΪÐýתÖÐÐÄ£¬½« A µãÄæÊ±ÕëÐýתһ¶¨µÄ½Ç¶È¦ÁÖÁ B µã£¬Éè´Ëʱ B µãµÄ×ø±êÊÇ(x,y)£¬ÄÇô´Ëʱ y µÄÖµ¾Í½Ð×ö¦ÁµÄÕýÏÒ£¬¼Ç×÷ sin¦Á£»´Ëʱ x µÄÖµ¾Í½Ð×ö¦ÁµÄÓàÏÒ£¬¼Ç×÷ cos¦Á£»y Óë x µÄ±ÈÖµ y/x ¾Í½Ð×ö¦ÁµÄÕýÇУ¬¼Ç×÷ tan¦Á¡£

»¹ÓÐÒ»¸öºÜÖØÒªµÄ¹«Ê½£ºÔ²µÄ²ÎÊý·½³Ì£ºÒÔµãO£¨a£¬b£©ÎªÔ²ÐÄ£¬ÒÔrΪ°ë¾¶µÄÔ²µÄ²ÎÊý·½³ÌÊÇ x=a+r*cos¦È, y=b+r*sin¦È, £¨ÆäÖЦÈΪ²ÎÊý£©
µ½ÕâÀïΪֹ£¬Ë¼Â·¾ÍÇåÎúÁË£¬ÒÔÏÂÊÇgenerateCenterPointInRadarµÄ·½·¨ÊµÏÖ£º

private func generateCenterPointInRadar() -> CGPoint{  
var angle = Double(arc4random()) % 360
var radius = Double(arc4random()) % (Double)((self.bounds.size.width - itemSize.width)/2)
var x = cos(angle) * radius
var y = sin(angle) * radius
return CGPointMake(CGFloat(x) + self.bounds.size.width / 2, CGFloat(y) + self.bounds.size.height / 2)
}

ÎÒÃÇÏÈÔÚ360¡ãÒÔÄÚËæ»úÉú³ÉÒ»¸ö½Ç¶È(¦È)£¬È»ºóÔÚ°ë¾¶·¶Î§ÄÚËæ»úÉú³ÉÒ»¸öÖµ£¬¾Íµ±×÷ÊÇÒ»¸öеİ뾶r£¬ÀûÓù«Ê½ÎÒÃǵõ½ÁËx¡¢yµÄµã£¬ÓÐÔ²ÐÄ£¨a£¬b£©Îª¸¨Öú£¬¾ÍÄÜÉú³ÉÒ»¸ö×ø±êÁË£¬Õâ¸ö×ø±êÔÚ·µ»ØÊ±¾ÍÒѾ­ÊÇ»ùÓÚÔ²ÐĵÄÁË£¬ËùÒÔÔÚaddOrReplaceItemÕâ¸ö½Ó¿ÚÀïÎÒÃÇÄõ½×ø±êºó¾ÍÄÜÖ±½Óµ±×÷centerÀ´ÓÃÁË£¬Õâʵ¼ÊÉÏÒ²ÊÇÍêÈ«²ÉÓõĹ«Ê½µÄËã·¨¡£

ÕâÑùÒ»À´£¬addOrReplaceItemÕâ¸ö½Ó¿ÚÒ²Íê³ÉÁË£¬ÎÒÃǰÑViewControllerÀïµÄµ÷ÓÃÒ²ÍêÉÆÒ»Ï£¬¾ßÌåµÄ£¬ÔÚviewDidLoad·½·¨µÄ×îºóÔö¼ÓÒ»¸öTimer£¬Õâ¸öTimerÿ0.5Ãëµ÷ÓÃÒ»´ÎaddOrReplaceItem£º

NSTimer.scheduledTimerWithTimeInterval(0.5, target: radarView,
 selector: Selector("addOrReplaceItem"), userInfo: nil, repeats: true)

TimerÔÚ²»ÓõÄʱºòÒ»¶¨Òªµ÷ÓÃinvalidate()·½·¨£¬²¢ÇÒÒªÔÚViewControllerÎö¹¹Ö®Ç°£¬²»È»ViewController²»»á±»ÊÍ·Å£¬Ò²¾ÍÓÀÔ¶²»»á±»Îö¹¹¡£ÕâÀïÎÒÃǾͲ»¿¼ÂÇÄÇô¶àÁË£¬±Ï¾¹Ö»ÓÐÒ»¸öÒ³Ãæ£¬¶øÇÒÔÚÕæÊµ³¡¾°ÀïÒ²²»»áÕâôȥÓ㬸ü¶àµÄÇé¿öÊÇÔÚÍøÂçÇëÇ󻨵÷µÄʱºòÈ¥´¦Àí¡£

ÕâôһÀ´£¬¶¯Ì¬Ôö¼õ²¿·ÖÒ²Íê³ÉÁË£¬µ«ÊÇÍêÃÀÁËÂð£¿ÏÔȻûÓС£

ÓÅ»¯

ÓÅ»¯Ò»

ÓëÆä˵ÊÇÓÅ»¯£¬²»Èç˵ÊÇÐÞ¸´Bug¡£ºÜÃ÷ÏÔ£¬ÔÚÉÏÒ»²½ÖУ¬ÎÒÃǶ¯Ì¬Éú³ÉµÄÔªËØÖØµþÁË£¬Õâ²»ÄÜÈÃÈ˽ÓÊÜ£¬¶øÎÒÃÇÖ»ÒªÉÔ΢×öЩ¸Ä±ä¾ÍÄÜ·ÀÖ¹ÕâÖÖÇé¿öµÄ·¢Éú¡£

ÎÒÃÇÏÖÔÚÔÚÉú³Éÿ¸öitemµÄcenterµÄʱºò£¬Ã»ÓкÍÒÑÓеÄitem½øÐбȽϣ¬ÕâÊÇÒ»¸ö±È½ÏºÄÐÔÄܵIJÙ×÷£¬Èç¹ûÄãµÄitemSize¹ý´ó£¬maxCount¹ý¶à£¬ÕâÉõÖÁÄܵ¼ÖÂËÀÑ­»·£¬Èç¹ûÊÇÄÇÑùµÄ»°£¬Äã¿ÉÄÜÔÚ¶ÔitemSizeÒÔ¼°maxCount×ö³öÏÞÖÆµÄͬʱ£¬Ò²¶ÔÑ­»·µÄÊýÁ¿Ò²½øÐпØÖÆ£¬Èç¹ûÔÚÉú³ÉÒ»¸öitemµÄcenterµÄʱºò£¬½øÐÐÁ˹ý¶àµÄÑ­»·£¬¾Í¿ÉÒÔÊÓΪ½øÈëËÀÑ­»·ÁË£¬ÔÚÕâÖÖÇé¿öÏ£¬ÄãÖ»ÄÜÖØÐ¼ÆËãÒÑÓеÄcenters¡£ÕâÀï²»¿¼ÂÇÕâÖÖ¼«¶ËÇé¿ö£¬ÒòΪĿǰµÄitemSizeºÍmaxCountµÄÅäºÏ£¬²»»á³öÏÖËÀÑ­»·¡£

ÎÒÃÇÌí¼ÓÒ»¸öitemFrameIntersectsInOtherItem˽Óз½·¨À´ÅжÏÊÇ·ñºÍ֮ǰÉú³ÉµÄcenterÓÐÁËÖØµþ£º

private func itemFrameIntersectsInOtherItem (frame: CGRect) -> Bool {  
for item in items {
if CGRectIntersectsRect(item.frame, frame) {
return true
}
}
return false
}

½ÓÊÕÒ»¸öframe£¬È»ºóºÍÿһ¸öitem±È½Ï£¬Èç¹ûÖØµþ·µ»Øtrue£¬·´Ö®Ôò·µ»Øfalse¡£

ÔÚaddOrReplaceItem·½·¨ÀïµÄ¸ÄÔ죺

...  
do {
var center = generateCenterPointInRadar()
radarButton.center = CGPointMake(center.x, center.y)
} while (itemFrameIntersectsInOtherItem(radarButton.frame))
...

°ÑÉèÖÃcenterµÄµØ·½ÓÃÒ»¸ödo-whileÑ­»·°ü×°ÆðÀ´¼´¿É¡£ÕâôһÀ´£¬Éú³ÉµÄÔªËØ¾Í²»»áÖØµþÁË¡£

ÓÅ»¯¶þ

ÎÒ´òËã¸øÃ¿Ò»¸öitemµÄÏÔʾºÍÒÆ³ýÔö¼ÓÒ»µã¶¯»­Ð§¹û£¬ÒÔÃâÏÔµÃÌ«ÉúÓ²£¬²¢ÇÒÓÃÅÉÉúÀàµÄ·½Ê½À´ÊµÏÖ£º

class PRButton: UIButton {  

init(frame: CGRect) {
super.init(frame: frame)
self.alpha = 0
}

override func didMoveToWindow() {
super.didMoveToWindow()
if self.window {
UIView.animateWithDuration(1, animations: {
self.alpha = 1
})
}
}
}

°ÑaddOrReplaceItemÖеÄUIButtonÌæ»»ÎªPRButton£¬ÕâÑùÔÚitem±»Ìí¼ÓµÄʱºò£¬ÓÐÒ»¸ö¼òµ¥µÄ¹ý¶É¶¯»­£¬µ±ÎÒ×¼±¸ÖØÐ´removeFromSuperviewµÄʱºò£¬Óöµ½ÁËÒ»µãÎÊÌ⣺

ÔÚSwiftÀïÃæ£¬±Õ°üÊDz»ÄÜÓÃsuperµÄ£¬ÄÇÖ»ÄÜÕâÑùÁË£º

override func removeFromSuperview() {  
UIView.beginAnimations("", context: nil)
UIView.setAnimationDuration(1)
self.alpha = 0
UIView.setAnimationDidStopSelector(Selector("callSuperRemoveFromSuperview"))
UIView.commitAnimations()
}

private func callSuperRemoveFromSuperview() {
super.removeFromSuperview()
}

ÔËÐÐÆðÀ´Ó¦¸Ã¿ÉÒÔ¿´µ½ÍêÕûµÄЧ¹ûÁË¡£

ÓÅ»¯Èý

Õâ¸öͬÑùÒ²ÊÇÐÞ¸´Bug¡£Èç¹ûÔÚ¶¯»­²¥·ÅµÄʱºòÄã°´ÏÂHome¼ü£¨Ä£ÄâÆ÷°´ÏÂcommand+shift+h£©£¬¾Í»á³öÏÖÏÂÃæÕâÖÖÇé¿ö£º

ÕâÊÇÒòΪÔÚ°´ÏÂHome¼üµÄʱºò£¬ËùÓе͝»­±»ÒƳýÁË£¬¾ßÌåµÄ£¬Ã¿¸öLayer¶¼µ÷ÓÃÁËremoveAllAnimations·½·¨¡£ÎÒÃÇÈç¹ûÏëÒªÔڻص½Ó¦ÓóÌÐòµÄʱºò¼ÌÐø¶¯»­£¬ÐèÒª¼àÌýϵͳµÄUIApplicationDidBecomeActiveNotification֪ͨ£º

...  
weak var animationLayer: CALayer?
init(frame: CGRect) {
super.init(frame: frame)

NSNotificationCenter.defaultCenter().addObserver(self,
selector: Selector("resume"),
name: UIApplicationDidBecomeActiveNotification,
object: nil)
}
func resume() {
if self.animationLayer {
self.animationLayer?.removeFromSuperlayer()
self.setNeedsDisplay()
}
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}

ÕâÑùÒ»À´£¬¶¯»­¾Í¿ÉÒÔÔڻص½Ó¦ÓóÌÐòµÄʱºòÖØÐ¿ªÊ¼ÁË£¬ÎÒ°ÑanimationLayeÒÔweakµÄ·½Ê½ÒýÓõ½ÁËÊôÐÔÀïÃæ£¬ÕâÊÇΪÁËÔÚresumeÀïºÃ·½±ãÅжϡ£

   
3794 ´Îä¯ÀÀ       30
 
Ïà¹ØÎÄÕÂ

ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖÓë̽ÌÖ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
 
Ïà¹ØÎĵµ

Android_UI¹Ù·½Éè¼Æ½Ì³Ì
ÊÖ»ú¿ª·¢Æ½Ì¨½éÉÜ
androidÅÄÕÕ¼°ÉÏ´«¹¦ÄÜ
Android½²ÒåÖÇÄÜÊÖ»ú¿ª·¢
Ïà¹Ø¿Î³Ì

Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
Androidϵͳ¿ª·¢
AndroidÓ¦Óÿª·¢
ÊÖ»úÈí¼þ²âÊÔ
×îл¼Æ»®
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢ 6-12[ÏÃÃÅ]
È˹¤ÖÇÄÜ.»úÆ÷ѧϰTensorFlow 6-22[Ö±²¥]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 6-30[±±¾©]
ǶÈëʽÈí¼þ¼Ü¹¹-¸ß¼¶Êµ¼ù 7-9[±±¾©]
Óû§ÌåÑé¡¢Ò×ÓÃÐÔ²âÊÔÓëÆÀ¹À 7-25[Î÷°²]
ͼÊý¾Ý¿âÓë֪ʶͼÆ× 8-23[±±¾©]

androidÈË»ú½çÃæÖ¸ÄÏ
AndroidÊÖ»ú¿ª·¢£¨Ò»£©
AndroidÊÖ»ú¿ª·¢£¨¶þ£©
AndroidÊÖ»ú¿ª·¢£¨Èý£©
AndroidÊÖ»ú¿ª·¢£¨ËÄ£©
iPhoneÏûÏ¢ÍÆËÍ»úÖÆÊµÏÖ̽ÌÖ
ÊÖ»úÈí¼þ²âÊÔÓÃÀýÉè¼ÆÊµ¼ù
ÊÖ»ú¿Í»§¶ËUI²âÊÔ·ÖÎö
ÊÖ»úÈí¼þ×Ô¶¯»¯²âÊÔÑо¿±¨¸æ


Android¸ß¼¶Òƶ¯Ó¦ÓóÌÐò
AndroidÓ¦Óÿª·¢
Androidϵͳ¿ª·¢
ÊÖ»úÈí¼þ²âÊÔ
ǶÈëʽÈí¼þ²âÊÔ
AndroidÈí¡¢Ó²¡¢ÔÆÕûºÏ


ÁìÏÈIT¹«Ë¾ android¿ª·¢Æ½Ì¨×î¼Ñʵ¼ù
±±¾© Android¿ª·¢¼¼Êõ½ø½×
ijÐÂÄÜÔ´ÁìÓòÆóÒµ Android¿ª·¢¼¼Êõ
ijº½Ì칫˾ Android¡¢IOSÓ¦ÓÃÈí¼þ¿ª·¢
°¢¶û¿¨ÌØ LinuxÄÚºËÇý¶¯
°¬Ä¬Éú ǶÈëʽÈí¼þ¼Ü¹¹Éè¼Æ
Î÷ÃÅ×Ó Ç¶Èëʽ¼Ü¹¹Éè¼Æ